尽管友谊却无法进入基层

Map*_*ple 11 c++ inheritance friend

关于此错误有很多问题,所有答案似乎都暗示着向下转换是不可能的。至少据我所知,只有这个答案提到友谊是可能的解决方案。但是,以下代码(为清晰起见,删除了不相关的内容)无法编译:

class C;

class A {
    friend class C;  // this does not help
};

class B : protected A {
    friend class C;  // this does not help either
};

class C {
    public:
    void foo(A* a) {};
};

B b;
C c;

void bar()
{
    c.foo(&b);  // this produces error: class A is an inaccessible base of B
}
Run Code Online (Sandbox Code Playgroud)

为什么友情对参考无效?毕竟,“ C”完全有能力通过指向“ B”的指针来调用“ A”的受保护方法。

完整的错误是

prog.cc: In function 'void bar()':
prog.cc:20:13: error: 'A' is an inaccessible base of 'B'
   20 |     c.foo(&b);
Run Code Online (Sandbox Code Playgroud)

Gil*_*llé 14

您的代码与此等效:

B b;
C c;
A * a = &b; // <- This cast produces the error
c.foo(a);
Run Code Online (Sandbox Code Playgroud)

你无法施展&b作为A*,因为基类是受保护的,无论友谊C


Rei*_*ica 13

问题在于,从B*到的转换A*(需要友谊)不会在的成员函数中发生C,而是在包含b和的代码的上下文中发生c(即,不相关的函数bar())。

如果您在C接受中创建了一个成员函数B*,然后foo()从中调用它,它将很好地工作。那样的话,转换将在C具有必要访问权限的环境下发生(由于友谊)。