来自 https://en.cppreference.com/w/cpp/language/dynamic_cast :
dynamic_cast < new_type > ( expression )
3) If
new_type
is a pointer or reference to Base, and the type ofexpression
is a pointer or reference to Derived, where Base is a unique, accessible base class of Derived, the result is a pointer or reference to the Base class subobject within the Derived object pointed or identified byexpression
. (Note: an implicit conversion andstatic_cast
can perform this conversion as well.)
示例代码:
#include <iostream>
using namespace std;
class A {
//public:
// virtual ~A() {
//
// }
};
class B : public A {
};
class C : public B {
};
class D : public B, public A {
};
int main()
{
D* pd = new D;
if (B* pa = dynamic_cast<B*>(pd)) {
cout << "1";
}
return 0;
}
VC++下无报错和警告
warning: direct base 'A' inaccessible in 'D' due to ambiguity
在 gcc 下,link
我不应该期待编译错误吗?
现在我发现如果我尝试转换 D*
至 A*
,会发生错误,但如上所述,来自 D*
至 B*
, 没有错误。
int main()
{
D* pd = new D;
if (A* pa = dynamic_cast<A*>(pd)) {
cout << "1";
}
return 0;
}
最佳答案
在这种情况下,unique 意味着 Derived 包含 new_type
仅一次,而不是 Derived 派生自单个基类。
因此,在您的示例中,B
是唯一的,因为 D
只包含它一次。
在你的例子中,D
包含 A
两次(一次直接,一次通过 B
),所以无法转换为 A
,因为 A
不是唯一的。
请注意,“遏制”很重要。因此,在此示例中,C
两次从 Base
派生,但它很好,因为 Base
是通过关键字 virtual< 继承的
:
struct Base { };
struct A: virtual Base { };
struct B: virtual Base { };
struct C: A, B { };
int main() {
C c;
dynamic_cast<Base &>(c);
}
(如果我没有使用virtual
,那么Base
就会有歧义)
注意:我会使用 static_cast
代替,因为在这种情况下它也可以进行转换。使用 dynamic_cast
在这里有点误导,因为转换将在编译时完成,而不是运行时。
关于c++ - 为什么允许 dynamic_cast 到非唯一基类类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52550064/