有继承的朋友类

Har*_*rry 9 c++ inheritance access-control friend

如果我有两个类继承如下:

class A
{
    ...
}

class B : public A
{
    ...
}
Run Code Online (Sandbox Code Playgroud)

第三类定义为朋友类A:

class C
{
    friend class A;
}
Run Code Online (Sandbox Code Playgroud)

我是否能够从class B(也是类型的对象A)所有成员访问,class C就像我首先定义class B了朋友类一样?

Mas*_*Man 12

friend船既不是遗传也不是传递.它是两个班级之间严格的一对一关系.

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
  }
};
Run Code Online (Sandbox Code Playgroud)

参考:"C++编程语言"Bjarne Stroustrup

更多解释(我的):如果friend船不是一个人,那将是封装的结束.需要注意的是B类可以访问private的成员A仅当类声明A声明Bfriend.B不能强制friend船舶A.

现在,如果友谊可以继承,那么有人只需要继承B来访问私人成员A,而没有A任何预防措施.此外,允许friend船舶传递将导致其他问题,因为现在B可能有一个friend C,而反过来可能有一个friend D,一直到Z.所有的B,C,D,...,Z现在可以访问Aprivate成员,这将是一场灾难.


v01*_*dya 6

由于某种原因,每个人都忘记了您可以访问从友谊给予者派生的类的虚拟私有函数。

#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;
}
Run Code Online (Sandbox Code Playgroud)

运行上面代码的输出是:

Parent
Child
Run Code Online (Sandbox Code Playgroud)

它起作用的原因很棘手,并且与该指针的传递方式有关(查找虚函数表)。如果您从函数声明中删除“virtual”关键字,您将失去这种能力。