c++ - 为什么允许 dynamic_cast 到非唯一基类类型?

标签 c++

来自 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 of expression 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 by expression. (Note: an implicit conversion and static_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;
}

link

最佳答案

在这种情况下,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/

相关文章:

c++ - 以 root 身份运行时出现段错误?

c++ - GetClipboardData(CF_HDROP) 剪切和粘贴失败

c++ - 由于字符数组到指针衰减而无法推导非类型模板参数?

c++ - 段错误 - 从指针到指针的 printf 值

c++ - 使用 boost::interprocess 编译链接器错误

c++ - 在 shared_ptr 的容器上使用 C++ std::equal

c++ - 当 ogl::Arrays 的默认构造函数运行时,Opencv2 崩溃

c++ - 'delete [] _v;' 是什么意思?

c++ - 打印给定总和的所有路径的函数(二叉树 C++)

c++ - 抛出逻辑错误异常或只是在库中中止?