big*_*iao 2 c++ dynamic-cast access-control private-inheritance
引自C++ Primer 5th 19.2.1.dynamic_cast运算符
dynamic_cast具有以下形式:
dynamic_cast<type*>(e)
dynamic_cast<type&>(e)
dynamic_cast<type&&>(e)
Run Code Online (Sandbox Code Playgroud)
其中type必须是类类型,并且(通常)命名具有虚函数的类.在第一种情况下,
e必须是有效的指针(第2.3.2节,第52页); 在第二,e必须是左值; 而在第三,e不能是左值.在所有情况下,类型
e必须是从目标类型公开派生的类类型,目标类型的公共基类,或者与目标类型相同.如果e有这些类型之一,那么演员表会成功.否则,演员表失败.
如果指针类型的dynamic_cast失败,则结果为0.如果对引用类型的dynamic_cast失败,则运算符抛出类型异常bad_cast
但是,我在这里写了一段代码片段:
struct A {};
struct B : private A // note: *private* inheritance
{
A* test() {
return dynamic_cast<A*>(this);
}
};
int main()
{
B b;
if(b.test()==nullptr)
throw 1;
}
Run Code Online (Sandbox Code Playgroud)
在上面的代码片段中,A它只是一个私有基础B,c ++入门没有考虑到它.但是,此代码段可以编译并运行而不会出错.底漆有错吗?
这一切都是引物部分的一个不幸的措辞.它将两种类型的演员阵容组合成一个句子,然后错过了结果.
转换为基类,不需要运行时强制转换操作.它是,因为TC说,纯粹是一种静态的结构.和TC引用一样,它需要一个可访问的基础,而不是公共基础.所以你的代码一切都很好.
对于运行时强制转换(向下转换),C++标准对操作数和动态强制转换中涉及的类型提出了要求,以使其成功.该类必须是公开派生的,否则实现没有义务成功转换继承链.我的意思是,它理论上可以使演员成功,但根据规范"运行时检查失败",这不会留下太多的余地.
但无论哪种方式,你的程序都没有任何错误会使它无法编译,也没有任何东西会导致任何类型的运行时错误.
如果我们将您的代码更改为强制转换而不是强制转换,那么这是一个甚至无法构建的示例:
struct A {};
struct B : private A // note: *private* inheritance
{
A* test(B* p) {
return dynamic_cast<A*>(p);
}
friend B* foo(A*);
};
B* foo(A* a) {
return dynamic_cast<B*>(a);
}
int main()
{
B b;
*foo(&b);
}
Run Code Online (Sandbox Code Playgroud)
A是的可访问基地B中foo,然而,是形成不良的铸造.
将引物重新引入过程的最小变化是将" 从目标类型公开派生的类类型"变为" 从目标类型可访问地派生的类类型".由于在公开的勘误表中没有任何类型,我们可以猜测这是一个尚未被指出的编辑错误.
| 归档时间: |
|
| 查看次数: |
151 次 |
| 最近记录: |