我们在这里上课B
,从类继承A
,并且它有一个friend
class C
。作为朋友,C
应该可以访问所有内容B
, 包括A
基类。
为了测试它,
- 首先我们创建一个
B
实例。
- 我们将其地址升级为
A*
- 然后我们尝试用
dynamic_cast<>
再次到B*
.
预期结果是取回原来的地址B
实例。
#include <cstdint>
#include <cstdio>
class A {
public:
virtual ~A() {};
};
class C;
class B : protected A { // <- this should be public to work! Why?
friend C;
};
class C {
public:
void doit() {
B *b = new B();
printf("b= %p\n", b);
A *a = static_cast<A*>(b);
printf("a= %p\n", a);
B *bb = dynamic_cast<B*>(a);
printf("bb=%p\n", bb);
delete b;
};
};
int main() {
C c;
c.doit();
return 0;
};
类似情况下的常见问题,即基类必须是多态的(这里由其空虚拟析构函数保证),在这里得到了解决。
然而,动态转换仍然不起作用:bb
应该有相同的地址b
.
我的实验表明,使其发挥作用的唯一方法是A
is a public
的基类B
。但...C
是...的朋友B
. 它甚至不起作用protected
.
为什么会这样呢?
如果重要的话,我使用 gcc-8。
将“dynamic_cast”视为全局函数。 “朋友C;”将友谊给予“class C”而不是“dynamic_cast”。
成员访问检查是在编译时进行的。
Dynamic_cast 在运行时检查基本可访问性。 RTTI 具有基本可访问性信息(请参阅 MS 实现 rtti.cpp;__RTDynamicCast),但没有友谊。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)