tags:

views:

298

answers:

3

Given a class such as:

class Person
{
private:
    char *name;

public:
    Person()
    {
        name = new char[20];
    }
    ~Person()
    {
        delete [] name;
    }
}

I want to print to print the name from an instance of this, using a statement like the following:

cout << myPerson << endl;

What do I need to do to define the << output operator for this class?

+11  A: 

add this in the class:

friend std::ostream& operator<< (std::ostream& out, const Person& P);

and then define the operator<< something like this:

std::ostream& operator<< (std::ostream& out, const Person& P) {
    out << P.name;
    return out;
}
jbradaric
I'd advice to add getName() and remove friend operator.
Mykola Golubyev
why do i need friend?
Yeah, it IS quite peculiar to have a private, accessor-less data member which can only be accessed through << tricks!
Alex Martelli
Alex Martelli
I'm not sure ostream can be const either. I might be wrong on this.
Skurmedel
Actually I'm certain of this.
Skurmedel
Stream operators declared friend is a very common pattern, and a good one too. Exposing private members through get/set accessors for the sole purpose of streaming is bad, because it exposes the said accessors to everyone. A friend streaming operator at least restricts the access to the clear context of reading from and writing to stream.
Remus Rusanu
Oops :( I apologise, ostream cannot be const. It's fixed now.
jbradaric
Yes but in this case I'm quite certain some other class would want to know the name of the person.
Skurmedel
That's what I am talking about. Without getName() people will start to use << to obtain Person name by parsing stringstream.
Mykola Golubyev
No, the correct way is to use friend for this. http://www.parashift.com/c++-faq-lite/input-output.html#faq-15.8 If somebody misuses << to get the name, that's their mistake.
markh44
BTW, the friend declaration still has const on the stream parameter.
markh44
So I need friend or not?I am confused!
I still don't agree that you need friend for it. If you in the future might need to have some other internal data printed out which is not exposed to other parts of the program it might matter. Otherwise it really doesn't.And if that need eventually arises I'm still doubtful. What kind of data should be hidden to other code but visible in print outs? The only thing I can come up with is debug info.
Skurmedel
operator<< has an excellent reason to access the private data of the class. In fact, it would be a member of the class if it were possible - so it should definitely be a friend. That's what friend is for.
markh44
And what is that reason?
Skurmedel
A: 

You can not do that directly from main() as name is declared as private here. You'll have to create a public fucntion and call that from main()

Like this:

class Person { private: char *name;

public:
Person()
{
       name = new char[20];
}
~Person()
{
    delete [] name;
}
void print()
{

 cout << myPerson << endl;
}

}

int main() {

Person p;

p.print();

return 0; }

Owais Lone
If I went this very dubious way at least I'd provide the ostream-).
Alex Martelli
+2  A: 

Define a member funtion print() that takes an ostream as an argument. Then let the overloaded operator<< call this member funtion. This way you can avoid using friend. Example:

void YourClass::print(ostream& out) const
{
    //implement printing ...
}
ostream& operator<<(ostream& out, const YourClass& m)
{
    m.print(out);
    return out;
}
Moberg