尽管有友谊,但无法进入的基类
Inaccessible base class despite friendship
关于这个错误有很多问题,所有的答案似乎都暗示着向下投射是不可能的。只有这个答案提到友谊是可能的解决方案,至少据我所知。但是,以下代码(为清楚起见,删除了不相关的内容(无法编译:
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
}
为什么友谊在参考上不起作用?毕竟,"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);
您的代码等效于以下内容:
B b;
C c;
A * a = &b; // <- This cast produces the error
c.foo(a);
您不能将&b
转换为A*
,因为基类受到保护,无论C
的友谊如何。
问题是从B*
到A*
(需要友谊的那个(的转换不是发生在C
的成员函数中,而是发生在包含b
和c
的代码的上下文中(即不相关的函数bar()
(。
如果您在接受B*
C
中创建了一个成员函数,然后从其中调用foo()
,则可以正常工作。这将使转换发生在具有必要访问权限C
的背景下(感谢友谊(。
在全局范围内,由于受保护的继承,B 不可见为 A。
只有B类本身,从B类继承的类和C类(因为友谊关系("知道"B继承了A。但世界其他地区(包括全球范围(没有。
所以要实现你想要的,你可以打电话
c.foo(&b)
在 C 范围内,例如使用一些包装器函数,例如(尽管设计决策很糟糕(:
#include <iostream>
#include <cstdlib>
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() {
B b;
foo(&b); // this call is OK within C-scope
}
private:
void foo(A* /*a*/) {
std::cout << "C::foo(A* a)n";
};
};
int main()
{
std::cout << "Hello, Wandbox!" << std::endl;
B b;
C c;
//c.foo(&b); // this produces error: class A is an inaccessible base of B
c.foo(); // this is calling c.foo(A*) internally
}
或直播:
相关文章:
- std::具有相同基类的类的变体
- 是否可以初始化不可复制类型的成员变量(或基类)
- 在C++中,是否可以基于给定的标识符创建基类的新实例,反之亦然
- 基类中的函数名称解析
- C++初始化基类
- 如何通过派生类函数更改基类中的向量
- 如何定义一个纯抽象基类
- 如何使用基类指针引用派生类成员
- 继承:构造函数,初始化C++11中基类的类C数组成员
- 使用基类指针创建对象时,缺少派生类析构函数
- 如何引用基类的派生类?
- 如果基类包含双指针成员,则派生类的构造函数
- 在模板基类中为继承类中的可选重写生成虚拟方法
- 为什么此派生对象无法访问基类的后递减方法?
- 公开最直接的基类模板名称
- 当基类是依赖类型时,这是一个缺陷吗
- 如何使基类的运算符对基类的可变参数数可见(请参阅下面的代码)?
- 模板基类中的静态变量
- 尽管有友谊,但无法进入的基类
- 友谊从派生类方法到基类成员