【发布时间】:2020-05-08 00:10:18
【问题描述】:
考虑以下程序
#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的这种指针转换是允许的?
【问题讨论】:
-
假设,可能有一个类继承自 A 和 C,因此通过动态转换从 C* 转换为 A* 是有效的 - 因为一般的转换不一定会失败。跨度>
标签: c++ polymorphism c++17 dynamic-cast nullptr