52

Does a subclass inherit, the main class' friend associations (both the main class' own and other classes friended with the main class)?

Or to put it differently, how does inheritance apply to the friend keyword?

To expand: And if not, is there any way to inherit friendship?

I have followed Jon's suggestion to post up the design problem:
C++ class design questions

Community
  • 1
  • 1
SE Does Not Like Dissent
  • 1,767
  • 3
  • 16
  • 36

4 Answers4

59

Friendship is not inherited in C++.

The standard says (ISO/IEC 14882:2003, section 11.4.8):

Friendship is neither inherited nor transitive.

Jon
  • 428,835
  • 81
  • 738
  • 806
  • Is there anyway to make it so it does inherit? – SE Does Not Like Dissent Sep 10 '11 at 10:31
  • 2
    @SSight3: No, you would need to make all classies in the hierarchy friends explicitly (possibly with the help of a source code preprocessor). If you have a specific problem to solve, ask about it explicitly. – Jon Sep 10 '11 at 10:33
21

You can create (static) protected methods in the parent that will allow you to do things like that.

#include <stdio.h>

class MyFriend
{
private:
    int m_member = 2;
    friend class Father;
};

class Father
{
protected:
    static int& getMyFriendMember(MyFriend& io_freind) { return io_freind.m_member; }
};

class Son : public Father
{
public:
    int doSomething(MyFriend& io_freind)
    {
        int friendMember = getMyFriendMember(io_freind);
        return friendMember;
    }
};

int main(){
    MyFriend AFriendOfFathers;
    Son aSonOfFathers;
    printf("%d\r\n", aSonOfFathers.doSomething(AFriendOfFathers));
    return 0;
}

This however bypasses encapsulation so you probably should take a second look at your design.

nimig18
  • 797
  • 7
  • 10
selalerer
  • 3,766
  • 2
  • 23
  • 33
11

friend only applies to the class you explicitly make it friend and no other class.

http://www.parashift.com/c++-faq-lite/friends.html#faq-14.4

balki
  • 26,394
  • 30
  • 105
  • 151
3

The answer is very simple: no, subclasses do not inherit friend associations. A friend can only access the private members of the class the association is declared in, not those of parents and/or children of that class. Although you might be access protected member of a superclass, but I'm not sure about that.

  • 2
    A Derived class can always access protected members of the Base class, it is through **Inheritance** not **Friend** ship. – Alok Save Sep 10 '11 at 10:36
  • @Als: `A Derived class can always access protected members of the Base class`. No, actually it depends. Depends on the kind of inheritance! – Nawaz Sep 10 '11 at 10:42
  • @Nawaz: Not really! [what are access specifiers should i inherit with private protected or public](http://stackoverflow.com/questions/5447498/what-are-access-specifiers-should-i-inherit-with-private-protected-or-public/%5d) should be a good read for you. – Alok Save Sep 10 '11 at 11:11
  • @Nawaz: Well what your comment says and what your program shows are two different things. – Alok Save Sep 10 '11 at 11:23
  • @Als: My comment says it depends on the kind of inheritance, and that is what I showed in my example. What else do you think my example shows? – Nawaz Sep 10 '11 at 11:28
  • @Nawaz: There is a detail that makes it *different*: the class `C` that does not have access to the details of class `A`, does not *inherit from `A`*. It is a superclass of `C` the one that does inherit from `A`, and at that level, `B` can access all of the `protected` methods. The difference is probably subtle and the confusion understandable, but because `B` inherits privately from `A`, from the perspective of `C`, `A` is not a base class. – David Rodríguez - dribeas Sep 10 '11 at 11:42
  • @David: Why `A` is not base class of both `B` and `C`? Because `C` cannot access the protected members of `A`? – Nawaz Sep 10 '11 at 11:49
  • @Nawaz: From the perpective of `C`, `C` is not an `A`, you cannot convert a pointer to `C` to a pointer to `A`... Conceptually it does not quite fit the *is-a* relationship, mainly because `C` *is-a* `B`, but `B` *is-implemented-in-terms-of* `A`. Again, this is highly arguably, and the best argument to your position would be that `C` can *override* methods from `A`, so there is an inheritance relationship there... Is `C` an `A`? Not at the `C` level, you cannot use `*this` in place of an `A&`, even if at the `B` level, a `C` object can be used to obtain an `A&` and use an override in `C`... – David Rodríguez - dribeas Sep 10 '11 at 12:45
  • ... again, quite arguable, and you can always say that whether `C` *knows* or not, it is an `A`, and you would be right. But that since `C` does not *know* that it is an `A`, it cannot access the `A` subobject. – David Rodríguez - dribeas Sep 10 '11 at 12:50
  • @David: `From the perpective of C, C is not an A, you cannot convert a pointer to C to a pointer to A`. Well, that is what proves my point that it depends on the kind of inheritance, as I said in my very first comment. If you derived publicly everywhere, then the problem which you see, would not be there. – Nawaz Sep 10 '11 at 13:11