Friend of a parent access to children

For everyone, just starting with C++ or programming at all. Ask newbie questions in this forum!

Moderators: Darobat, RecursiveS, Dante Shamest, Bugdude, Wizard

Friend of a parent access to children

Postby aas029 » Mon Nov 02, 2009 8:59 pm

Hello,

The common/classical explanation for the statement "c++ friendship is not inherited" is that if class X declares class P as a friend, then children of P are not considered friends of X.

There is another scenario which I don't know (or care :) whether it makes any sense from OO perspective but I still want to know what the expected outcome is from C++ perspective.

The scenario is that a parent class declares another class a friend. We'll call the latter parentFriend. What access would parentFriend have to members of class parent that are inherited inside various 'types' of children.

Below is the small piece of code demonstrating the relations/question.
I ran the code and know the answer (not posted here, slightly different for 2 different compilers) but I don't quite understand the results I got. I want to know the expected by design behavior (assuming defined).

class parentFriend;
class parent {
friend class parentFriend;
public: void f1(){};
protected: void f2(){};
private: void f3(){};
};
class childpub: public parent {};
class childprot: protected parent {};
class childprv: private parent {};
class parentFriend {
public:
void f(){
/* which of the following 6 statements will compile? why? why not?*/
parent p; p.f1(); p.f2(); p.f3(); // these will
childpub cpub; cpub.f1(); cpub.f2(); cpub.f3(); // (1)
childprot cprot; cprot.f1(); cprot.f2(); // (2)
cprot.f3(); //(3)
childprv cprv;
cprv.f1(); // (4)
cprv.f2(); // (5)
cprv.f3(); // (6)
}
};

Thanks in advance for any hints. This is neither related to any practical problem nor in any way a suggestion the above code is a pattern that makes any sense OO-wise.
aas029
 
Posts: 4
Joined: Mon Nov 02, 2009 8:55 pm

Re: Friend of a parent access to children

Postby Alvaro » Tue Nov 03, 2009 7:26 am

(1) should work. Everything else shouldn't, since the function members of `parent' are not accessible.

gcc-4.0.1 (the only compiler I have handy) let's me compile (2), but this seems like a mistake. I tried Comeau C/C++ online and it agreed with my interpretation.
User avatar
Alvaro
Moderator
 
Posts: 5167
Joined: Mon Sep 22, 2003 4:57 pm
Location: NY, USA

Re: Friend of a parent access to children

Postby aas029 » Tue Nov 03, 2009 9:44 am

Thanks Alvaro!!

Yes, (1) worked for both compilers I tried too. It makes sense for it to work even thou the generic statement "c++ friendship is not inherited" may be a bit misleading to someone new, who may think it has anything to do with this scenario (as oppose to the access from a child to class that declared the parent as a friend). This is the first reason why I submitted this question. I have done a little bit of research on this and have not come across any source that explicitly mentions this scenario.

In the light of the generic statement "c++ friendship is not inherited" (as oppose to more elaborate/precise rules from the standard), one may think the latter 2 parts of (1) should not work as the members (f2() and f3()) are now part of the child - not the parent - and any parent friendship should not play a role. Apparently it does.

The difference in compilers' results I got was only for (2) and (3). One compiler allowed both, another allowed only (2) - either way, cannot understand why. The output from Comeau and your interpretation make sense - that I can understand.

(4),(5) and (6) don't compile on both compilers I tried. So there results for these are consistent.

Hopefully someone will explain what is expected based on the standard (if the behavior is defined) and whether g++'s output is expected.
aas029
 
Posts: 4
Joined: Mon Nov 02, 2009 8:55 pm

Re: Friend of a parent access to children

Postby Alvaro » Tue Nov 03, 2009 12:39 pm

I tried to read the relevant part of the standard, but it's very unclear. I am thinking of filing a bug report with gcc, since more recent versions seem to do the same thing.

My main objection to allowing the parent's friend class to access data through the protected inheritance is that a change in that inheritance (for instance, making the class derive from a different base) should be guaranteed to only affect the modified class, its friends, its derived classes and the friends of its derived classes. With gcc's interpretation of the rules there is no such guarantee.
User avatar
Alvaro
Moderator
 
Posts: 5167
Joined: Mon Sep 22, 2003 4:57 pm
Location: NY, USA

Re: Friend of a parent access to children

Postby aas029 » Tue Nov 03, 2009 2:41 pm

Thanks a lot Alvaro! I posted the same question on other forums and will update you if I hear anything specific.

I'm relatively new to C++ and seeing how rich it's, I was wondering how all different combinations/permutations are checked.

Here is another related thing I tried in the same function. The same compiler that allowed some access to the cprot object (for f1() and f2()), refused to do so (did the right thing per your input) when I tried to do the same using pointer. You can try it with the g++ version you have. My guess you'll see the same errors below. This makes the compiler behavior even more puzzling (at least to me).

parent* ptr2p;
ptr2p = &cpub; ptr2p->f1(); ptr2p->f2(); ptr2p->f3(); // all ok here, just for reference
ptr2p = &cprot; // error: `parent' is an inaccessible base of `childprot'
ptr2p = &cprv; // error: `parent' is an inaccessible base of `childprv'

Again, I'm new to c++. So whether the above makes any sense OO-wise or otherwise is not the point/question. I'm only trying to check the access.
aas029
 
Posts: 4
Joined: Mon Nov 02, 2009 8:55 pm

Re: Friend of a parent access to children

Postby Alvaro » Tue Nov 03, 2009 2:46 pm

It looks like g++ lets me do it through a pointer as well, which again seems wrong.
Code: Select all
class Friend;

struct Base {
  friend class Friend;
  void f(){}
};

class Derived : protected Base {
};

class Friend {
public:
  void f() {
    Derived d;
    Base *b=&d;
    b->f();
  }
};
User avatar
Alvaro
Moderator
 
Posts: 5167
Joined: Mon Sep 22, 2003 4:57 pm
Location: NY, USA

Re: Friend of a parent access to children

Postby aas029 » Tue Nov 03, 2009 5:01 pm

Interesting to know. Thanks again Alvaro!

If I'm not mistaken, my g++ version is 3.2.3 and unless I missed something it allowed 'normal' access (cprot.f1(); cprot.f2();) but did not like the one using the pointer (this statement ptr2p = &cprot; // produced error). This is worse than what you reported (what you saw may be wrong but at least consistently wrong :)
aas029
 
Posts: 4
Joined: Mon Nov 02, 2009 8:55 pm


Return to For Beginners

Who is online

Users browsing this forum: No registered users and 1 guest

cron