当目标指针不是基类的类型时,为什么允许dynamic_cast为多态类生成 null 指针?

Why is the dynamic_cast allowed to yield a null-pointer for polymorphic classes when the destination pointer is not of the type of a base class?

本文关键字:指针 cast 多态 dynamic null 基类 目标 类型 为什么      更新时间:2023-10-16

考虑以下程序

#include <iostream>
#include <iomanip>
struct A
{
};
struct C
{
};
int main()
{
C *pc = nullptr;
A *pa1 = dynamic_cast<A *>( pc );
std::cout << "pa1 == nullptr is " << std::boolalpha << ( pa1 == nullptr ) << 'n';
A *pa2 = pc;
std::cout << "pa2 == nullptr is " << std::boolalpha << ( pa2 == nullptr ) << 'n';
}

对于两个指针声明 pa1 和 pa2,编译器报告不允许此类初始化的错误。

例如,clang HEAD 10.0.0 编译器发出以下错误。

prog.cc:19:14: error: 'C' is not polymorphic
A *pa1 = dynamic_cast<A *>( pc );
^                  ~~
prog.cc:23:8: error: cannot initialize a variable of type 'A *' with an lvalue of type 'C *'
A *pa2 = pc;
^     ~~
2 errors generated.

现在让我们使 C 类成为多态类。

#include <iostream>
#include <iomanip>
struct A
{
};
struct C
{
virtual ~C() = default; 
};

int main()
{
C *pc = nullptr;
A *pa1 = dynamic_cast<A *>( pc );
std::cout << "pa1 == nullptr is " << std::boolalpha << ( pa1 == nullptr ) << 'n';
A *pa2 = pc;
std::cout << "pa2 == nullptr is " << std::boolalpha << ( pa2 == nullptr ) << 'n';
}

只有第二个声明会产生错误。dynamic_cast有效。

rog.cc:22:8: error: cannot initialize a variable of type 'A *' with an lvalue of type 'C *'
A *pa2 = pc;
^     ~~
1 error generated.

允许这种dynamic_cast指针转换的原因是什么?

允许这种dynamic_cast指针转换的原因是什么?

因为dynamic_cast运行时运行,到那时发出编译器错误为时已晚。

如果转换失败,dynamic_cast返回nullptr。 您需要检查这一点,然后在需要时进行处理。