代码之家  ›  专栏  ›  技术社区  ›  Rick Jim DeLaHunt

为什么允许动态类型转换为非唯一的基类类型?

c++
  •  2
  • Rick Jim DeLaHunt  · 技术社区  · 6 年前

    https://en.cppreference.com/w/cpp/language/dynamic_cast :

    dynamic_cast < new_type > ( expression )

    3) 如果 new_type 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下无错误或警告++

    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;
    }
    

    link

    2 回复  |  直到 6 年前
        1
  •  3
  •   geza    6 年前

    在这种情况下, 意味着 new_type

    所以,在你的例子中, B D 包含 只有一次。

    D A 两次(一次直接,一次通过 B A 不能做,因为 A 不是唯一的。

    注意,“遏制”才是最重要的。在这个例子中, C Base 两次,但它是好的,因为 底座 是用关键字继承的 virtual :

    struct Base { };
    struct A: virtual Base { };
    struct B: virtual Base { };
    struct C: A, B { };
    
    int main() {
        C c;
        dynamic_cast<Base &>(c);
    }
    

    事实上的 底座 可能会模棱两可)

    注意:我会用 static_cast 相反,在这种情况下,它也可以做演员。使用 dynamic_cast 这里有点误导,因为转换将在编译时完成,而不是在运行时完成。

        2
  •  0
  •   Tien Do    6 年前

    该警告是由多重继承模型中的间接基类问题引起的。 D 有两个基类的副本 A B . 当基类被指定为虚拟基类(与@geza示例相同)时,虚拟基类之间只共享一个基类的数据成员副本。

    class A {
    public:
        A() {}
    };
    
    class B : virtual public A {
    public:
        B() : A() {}
    };
    
    class C : public B, virtual public A {
    public:
        C() : B() {}
    };
    
    int main()
    {
      A* pa = static_cast<A *>(new C()); // no more warning since A is virtual
      return 0;
    }
    

    这里有很好的解释: Multiple Base Classes .