dynamic_cast类型不完整的问题

dynamic_cast issue with incomplete type

本文关键字:问题 cast 类型 dynamic      更新时间:2023-10-16
class A 
{
  public:
     virtual void func() {
      cout<<" func():: in class A"<< endl;
     }
     void func1(){
     cout<<"func1():: in class A";
     }
};
class B: public A {
 public:
 void func() {
      cout<<" func():: in class B"<< endl;
     }
     void func1(){
     cout<<"func1():: in class B";
     }
};
int main()
{
 A a;
 A* pa = &a;
 B* pb = dynamic_cast<B*>(pa);
 pb->func1();
 return 0;
}

虽然pb指向一个不完整的类型,dynamic_cast会返回null。但是为什么在这种情况下它不会崩溃?

由于B类中的func1不访问任何成员变量(或虚函数),因此它不使用隐式this指针,因此在这种情况下不会崩溃。

请注意,这是未定义的行为,因此它可能会在不同的编译器(或编译器版本)中崩溃(或执行意外操作),因此不要依赖此行为。

您有一个指向A实例的A *,而不是实际指向B实例A *。这就是为什么dynamic_cast返回一个类型的 null 指针 B * ,它与这些是不完整的类型或任何内容无关(在链接的代码中,AB 都是完整的类型),因此这是dynamic_cast定义的行为。但是,在此之后将访问空指针;聪明的编译可以知道dynamic_cast在这一点上可能会失败,并且pb->func1();可以做任何事情,包括导致空指针异常或根本不会导致任何事情,甚至在不B的东西上调用pb1->func


类型不完整的示例如下:

#include <iostream>
using namespace std;
class A {
public:
    virtual void func() {
        cout << "func():: in class A" << endl;
    }
    void func1(){
        cout<< "func1():: in class A";
    }
};
class B;
int main() {
    A a;
    A* pa = &a;
    B* pb = dynamic_cast<B*>(pa);
    return 0;
}

现在,如果你用 G++ 编译它,你会得到

y.cc: In function ‘int main()’:
y.cc:20:32: error: cannot dynamic_cast ‘pa’ (of type ‘class A*’) to 
     type ‘class B*’ (target is not pointer or reference to complete type)
     B* pb = dynamic_cast<B*>(pa);

这都是理智的C++编译器会拒绝这样的代码。