overloading operator<< in derived classes

Hey everyone, my first post in here. I'm having some serious problem with a program I'm making. I want to overload the <<, using ostream, and I'm having problems with it in the derived classes I'm using.


This is my base class (I've only put the operations related to this problem, and I'll do the same with the next class):

class Pessoa
{
Pessoa(const Pessoa &);
Pessoa & operator=(const Pessoa&);
friend ostream & operator<<(ostream &, const Pessoa &);

}

Pessoa::Pessoa(const Pessoa & pessoa)
{
nome = pessoa.nome;
telemovel = pessoa.telemovel;
id = pessoa.id;

}



Pessoa & Pessoa::operator=(const Pessoa& pessoa)
{
id = pessoa.getId();
nome = pessoa.getNome();
telemovel = pessoa.getTelemovel();
return *this;
}

ostream & operator<<(ostream& os,const Pessoa& pessoa)
{
os << pessoa.getId() << " | " << pessoa.getNome() << " | " << pessoa.getTelemovel();
return os;
}

I've compiled this and it gave me no errors.

Now here's one of the derived classes:

class Utente: public Pessoa
{



public:

Utente(const Utente &);

Utente & operator=(const Utente &);
friend ostream & operator<<(ostream &, const Utente &);

};



Utente::Utente(const Utente &utent)
{
nome = utent.nome;
telemovel = utent.telemovel;
id = utent.id;
percentagem = utent.percentagem;
consulta_efect = utent.consulta_efect;
consulta_marc = utent.consulta_marc;
}


Utente & Utente::operator=( const Utente &utent)
{
Pessoa::operator=(utent);
percentagem = utent.percentagem;
consulta_efect = utent.consulta_efect;
consulta_marc = utent.consulta_marc;
return *this;
}



ostream & operator<<(ostream &os, const Utente &utent)
{
os << utent.id << " | " << utent.nome << " | " << utent.telemovel << " | " << utent.percentagem << " | " << utent.consulta_efect << " | " << utent.consulta_marc;
return os;

}

When I compile this class, it tells me there's a problem with ostream & operator<< and I get an enourmous wall of text. Does anyone have any idea how to solve this?

It appears you are attempting to have the derived class' operator<< output the base class members, which is possible, but only if the base class members are public or protected.

Probably the better way to write the derived class' operator<< is like this:

1
2
3
4
ostream& operator<<( ostream& os, const Utente& utent )
{
    return os << static_cast<const Pessoa&>( *this ) << /* derived class members */;
}


Unfortunately operator overloading and polymorphism combined don't exactly lend themselves to nice code; the cast is necessary to call the base class' operator<<.
The base class member-atributes are protected and the member-functions are public.

The code you wrote is giving me this error: invalid use of "this" in non member function.

Any ideas how to solve this?

By the way, I only intend to output in the program itself the derived class members, but for that I need to output the base class members. At least that's what I think.

Thanks for your input!
Oh, sorry,

static_cast<const Pessoa&>( utent )

I still get an enormous wall of text, this is really stressing.
Ok, can you post the error you are seeing?
error: no match for ‘operator<<’ in ‘std::operator<< [with _Traits = std::
char_traits<char>](((std::basic_ostream<char, std::char_traits<char>
>&)((std::basic_ostream<char, std::char_traits<char> >*)((std::
basic_ostream<char, std::char_traits<char> >*)std::operator<< [with
_Traits = std::char_traits<char>](((std::basic_ostream<char, std::
char_traits<char> >&)((std::ostream*)operator<<(((std::ostream&)
((std::ostream*)os)), ((const Pessoa&)((const Pessoa*)((const Pessoa&)
(&((const Utente*)utent)->Utente::<anonymous>))))))), ((const char*)" |
")))->std::basic_ostream<_CharT, _Traits>::operator<< [with _CharT =
char, _Traits = std::char_traits<char>](utent->Utente::percentagem))),
((const char*)" | ")) << utent->Utente::consulta_efect’
What is the type of percentagem?
It's a float. consulta_efect and consulta_marc are vector<Consulta>.

I've just noticed something. Utente is dependent on Consulta, and Consulta is dependent on Utente. I've solved this cyclical dependency by writing a forward declaration in these two classes. But I wonder if this is the cause of the problem.
Probably not.

Did you write an operator<< for vector<Consulta> and for Consulta?
For Consulta yeah, but I didn't for vector<Consulta>. How am I supposed to do that?
1
2
3
4
5
ostream& operator<<( ostream& os, const vector<Consulta>& v )
{
    // however you want this to appear
    return os;
}


I typically do (if you are familiar with the boost::lambda library)

1
2
   std::for_each( v.begin(), v.end(), os << '{' << boost::lambda::_1 << ',' );
   return os << '}';

But I didn't create a seperate class for every vector<something> in my program. Is it necessary to create them?
Yes. ostream does not have an operator<< overload that takes any arbitary vector, so you have to write one.

EDIT: here's a solution that might suffice for your purpose:
1
2
3
4
5
6
template< typename T, typename Alloc >
ostream& operator<<( ostream& os, const vector<T,Alloc>& v )
{
    // code here
    return os;
}


And now every vector in your program is ostreamable.
Last edited on
Where should I put that template?
You'll need to put it in a header file that gets included by any .cpp file that you intend to output a vector<>.
EDIT: Nevermind, I've got it working, thanks.
Last edited on
Topic archived. No new replies allowed.