Friend functions not inherited

A

Andrea Crotti

To my surprise I read that some time ago, so what I thought it could
work in fact it could not work.

Supposing I have two classes

class Base
friend operator<<(..)
// print base fields

class Extended : Base

Since the friend is not inherited I guess I have to declare it again,
but supposing I want to
- first call the << on the base class
- then call on the extended class

how should I do that?
A cast from the object itself ot it's base type?
 
A

Alf P. Steinbach /Usenet

* Andrea Crotti, on 04.11.2010 11:37:
To my surprise I read that some time ago, so what I thought it could
work in fact it could not work.

Supposing I have two classes

class Base
friend operator<<(..)
// print base fields

class Extended : Base

Since the friend is not inherited I guess I have to declare it again,
but supposing I want to
- first call the<< on the base class
- then call on the extended class

how should I do that?
A cast from the object itself ot it's base type?

Please post a minimal and complete example that exemplifies the problem.

See the FAQ item about how to post a question about Code That Does Not Work.


Cheers & hth.

- Alf
 
A

Andrea Crotti

Alf P. Steinbach /Usenet said:
Please post a minimal and complete example that exemplifies the problem.

See the FAQ item about how to post a question about Code That Does Not Work.


Cheers & hth.

- Alf

Nothing in particular that doesn't work, but this is what I wanted to do

--8<---------------cut here---------------start------------->8---
#include <iostream>

using namespace std;

class Base
{
friend ostream& operator<<(ostream& s, const Base& c);
};

class Extended : public Base
{
};

ostream& operator<<(ostream& s, const Base& b)
{
s << "base class" << endl;
return s;
}

ostream& operator<<(ostream& s, const Extended& e)
{
s << (*((Base *) &e)) << endl;
}

int main() {
Extended e;
cout << e;
return 0;
}
--8<---------------cut here---------------end--------------->8---

Which is rather ugly, is there a more automatic way to call something on
the base class in friend operators?
 
A

Andrea Crotti

Daniel T. said:
What's wrong with doing this?

class Base {
friend ostream& operator<<(ostream& s, const Base& c);
};

class Extended : public Base { };

ostream& operator<<(ostream& s, const Base& b) {
s << "base class" << endl;
return s;
}

int main() {
Extended e;
cout << e << '\n';
}

The above compiles fine and does what you wanted.

Right it does :)
I guess than that what I found on the internet was just wrong...
 
A

Andrea Crotti

Daniel T. said:
What's wrong with doing this?

class Base {
friend ostream& operator<<(ostream& s, const Base& c);
};

class Extended : public Base { };

ostream& operator<<(ostream& s, const Base& b) {
s << "base class" << endl;
return s;
}

int main() {
Extended e;
cout << e << '\n';
}

The above compiles fine and does what you wanted.


and what if you want instead want to print
"extended class base class"

So first calling the specialized method and from it the base class?

How do I tell to use Base::eek:perator<< in that case?
 
J

Juha Nieminen

Andrea Crotti said:
I guess than that what I found on the internet was just wrong...

No, it was not wrong. You simply misunderstood it.

The point is that the friend function in your example doesn't *need*
to be inherited to the derived class in order for it to work properly.
 
V

Victor Bazarov

and what if you want instead want to print
"extended class base class"

So first calling the specialized method and from it the base class?

How do I tell to use Base::eek:perator<< in that case?

You need to introduce polymorphism and call a virtual function in the
class Base. Something like

class Base {
...
virtual ostream& print(ostream& os) const
{
return os << "base class";
}
};

class Extended : public Base {
ostream& print(ostream& os) const
{
os << "extended class ";
return Base::print(os);
}
};

ostream& operator << (ostream& os, const Base& c)
{
return c.print(os);
}

V
 
A

Andrea Crotti

Daniel T. said:
You could do as Victor Bazarov suggested, but the following might be
simpler:

class Base { };

class Extended : public Base { };

ostream& operator<<(ostream& s, const Base& b) {
s << "base class" << endl;
return s;
}

ostream& operator<<(ostream& s, const Extended& b) {
s << static_cast<const Base&>(b);
s << "extended class" << endl;
return s;
}

int main() {
Extended e;
cout << e << '\n';
}

Ah yes I like this solution also thanks!
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,968
Messages
2,570,154
Members
46,702
Latest member
LukasConde

Latest Threads

Top