【发布时间】:2018-09-28 07:03:45
【问题描述】:
来自https://en.cppreference.com/w/cpp/language/dynamic_cast:
dynamic_cast < new_type > ( expression )
3) 如果
new_type是指向Base 的指针或引用,而expression的类型是指向Derived 的指针或引用,其中Base 是唯一,可访问的Derived 基类,结果是指向或由expression标识的派生对象中的基类子对象的指针或引用。 (注意:隐式转换和static_cast也可以执行此转换。)
示例代码:
#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++下无错误或警告
gcc下warning: direct base 'A' inaccessible in 'D' due to ambiguity,link
我不应该期待一个编译错误吗?
现在我发现如果我尝试将D* 转换为A* 会出现错误,但如上所述,从D* 转换为B*,没有错误。
int main()
{
D* pd = new D;
if (A* pa = dynamic_cast<A*>(pd)) {
cout << "1";
}
return 0;
}
【问题讨论】:
-
请您修改一下,这里没有多态结构。
-
@Bathsheba 但是这个强制转换规则 3) 并没有提到多态类型,我的目标是让它成为非多态的,在这里做一些实验。
-
在您的示例中,
B不是D的唯一基类吗?难怪它编译 -
在您的第一种情况下,
B在D中没有歧义,因此没有理由预期dynamic_cast<B*>(pd)会出现错误。 VC++ 对你很好,警告A是D的模棱两可的基数,但由于没有尝试将D *转换为A*,因此没有可诊断的错误。在第二种情况下,dynamic_cast<A*>(pd),有一个可诊断的错误,因为转换是不明确的。简而言之:两个编译器都是正确的,但是 VC++ 给出了一个额外的警告。编译器不需要给出警告。 -
@Rick,cppreference 的措辞可以稍微改进,但是“其中 Base 是 Derived 的唯一、可访问的基类”并不意味着“Derived 只有一个基类,它是 Base 类型”。这意味着“在 Derived 的(可能有多个)基类中只有一个 Base 类型的基类”。
标签: c++