Sign in to follow this  
maxest

[C++] Friend function inheritance

Recommended Posts

I accidentaly discovered that my function in the base class is "incorrectly" (I guess...) inherited in the derivative class.
I won't broadly discuss the circumstances, I just paste my code (a repro case):

Here's the header file:
[code]
#include <iostream>
#include <sstream>

using namespace std;



class Base
{
private:
friend ostream& operator << (ostream& os, const Base* b);
};



class Derivative: public Base
{
public:
friend ostream& operator << (ostream& os, const Derivative& d);
};
[/code]

Source file:
[code]
#include <iostream>
#include <sstream>

#include "header.h"

using namespace std;



ostream& operator << (ostream& os, const Base* b)
{
os << "from Base";
return os;
}



ostream& operator << (ostream& os, const Derivative& d)
{
os << "from Derivative";
return os;
}
[/code]

And the main file:
[code]
#include <iostream>
#include <sstream>

#include "header.h"



int main()
{
Derivative d;
cout << d << endl;
cout << &d << endl; // <- HERE

getchar();
return 0;
}
[/code]

What confuses me, is why the line marked as "HERE" works. The operator << for type const Base* should not work for Derivative class, because it's just a friend declaration. I thought friend declarations don't get inherited. Initally I had this declaration in public section of the Base class, but then I switched to private section (what you see above) and this still works. This gets me even more confused because private functions should not be inherited in derivative classes (given the public inheritance). What is the reasoning behind this behaviour?

Share this post


Link to post
Share on other sites
Your operator<< functions are non-member functions. They live outside the classes. There is no inheritance or anything like it going on. It's the same way that if you had a non-member, non-friend function void foo(Base *), it would automatically accept both Base pointers and Derivative pointers.

Share this post


Link to post
Share on other sites
[font="Arial"]So does that piecie of code:
[code]
class Base
{
private:
friend ostream& operator << (ostream& os, const Base* b);
};
[/code]
is actually seen by the compiler as:
[code]
class Base
{
private:
friend ostream& operator << (ostream& os, const Base* b);
};
ostream& operator << (ostream& os, const Base* b);
[/code]
or sth like that?[/font]

Share this post


Link to post
Share on other sites
I think I get it. This friend line simply causes two things: indicates the declaration of that function (in global scope) and at the same time says that it can access private members of Base. So just for keeping code clean it would be a good practice to explicitly make a declaration outside of the class and, if that function needs to access private members of the class, then make additional friend declaration.

Thanks SiScrane!

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this