Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

friend class with inheritance

If I have two Classes as follows with inheritance:

class A
{
    ...
}

class B : public A
{
    ...
}

And a third class with defined as a friend class A:

class C
{
    friend class A;
}

Will I be able to access from class B (which is also an object of type A) all members of class C as if I had defined class B the friend Class in the first place?

like image 768
Harry Avatar asked Dec 12 '12 16:12

Harry


People also ask

Can a friend class be inherited?

In C++, the friendship is not inherited. It means that, if one parent class has some friend functions, then the child class will not get them as friend.

Why friend function as there is inheritance?

Which means that if you have a function declared as friend then you can use this function in another class provided that the second class should also have friend function. Whereas in inheritance if we inherit a class then we have all the data members accessible in child class using public function of the class .

Do derived classes inherit friends?

In principle, a publicly derived class inherits access to every member of a base class except: its constructors and its destructor. its assignment operator members (operator=) its friends.

What does it mean when a class inherits another class?

Inheritance enables you to create new classes that reuse, extend, and modify the behavior defined in other classes. The class whose members are inherited is called the base class, and the class that inherits those members is called the derived class. A derived class can have only one direct base class.


2 Answers

For some reason everybody has forgotten that you can access virtual private functions of a class that derives from the friendship-giver.

#include <iostream>

class Friend;
class Parent
{
    friend class Friend;
private:
    virtual void nameYourself() { std::cout << "Parent" << std::endl; }
};

class Child : public Parent
{
private:
    virtual void nameYourself() { std::cout << "Child" << std::endl; }
};

class Friend
{
public:
    void foo(Parent *p) { p->nameYourself(); }
};

int main()
{
    Parent p;
    Child c;
    Friend f;
    f.foo(&p);
    f.foo(&c);
    return 0;
}

The output of running above code is:

Parent
Child

The reason why it works is tricky and has to do with how this pointer is passed (look up vtables). Were you to remove "virtual" keyword from the function declaration and you will lose this ability.

like image 87
v010dya Avatar answered Oct 31 '22 02:10

v010dya


friendship is neither inherited nor transitive. It is strictly one-one relationship between two classes.

class A {
  friend class B;  
  int Aries;
};

class B {
  friend class C;  
  int Taurus;
};

class C {
  int Leo;
  void Capricorn() {
    A a;
    a.Aries = 0;  // this wont work, C is not a friend of A.
                // friendship is not transitive
  }
};

class D : public C {
  void Gemini() {
    B b;
    b.Taurus = 0;  // this wont work, D is not a friend of B.
                   // friendship is not inherited
  }
};    

class E : public B {
  void Scorpio() {
    C c;
    c.Leo = 0; // this wont work either, friendship is not inherited
  }
};

Reference: "The C++ Programming Language" Bjarne Stroustrup

More explanation (mine): If friendship were not one-one, it would be the end of encapsulation. Note that B class can access private members of A only if the class declaration of A declares B as friend. B cannot enforce friendship on A.

Now, if friendship could be inherited, then someone just needs to inherit B to access private members of A, without A having any say in preventing it. Also, allowing friendship to be transitive would lead to other problems, since now B could have a friend C, who in turn could have a friend D, all the way to Z. All of B, C, D, ..., Z can now access A's private members, which would be a disaster.

like image 35
Masked Man Avatar answered Oct 31 '22 04:10

Masked Man