一览
- 本文目的
- 基类有虚函数
- 基类无虚函数
-
-
- 尾语
本文目的
最近秋招看到一个有意思的问题,对一个没有虚函数的对象使用dynamic_cast会发生什么情况。想一想平时基本没用过dynamic_cast,于是干脆写点代码验证一下各种情况。首先验证对有虚函数的基类的指针和引用(2种情况),指向基类本身和其派生类(2种情况),一共四种情况的结果。然后验证基类没有虚函数时的这四种情况。
基类有虚函数
1 #include<iostream>
2 #include<typeinfo>
3
4 using namespace std;
5
6 class A{
7 virtual void process(){}
8 };
9 class B:public A{
10 virtual void size(){}
11 };
12
13 int main(){
14 A* a1 = new B;
15 B* b1 = dynamic_cast<B*>(a1);
16 if(b1 == nullptr){
17 cout<<"b1 nullptr!!"<<endl;
18 }
19 A* a2 = new A;
20 B* b2 = dynamic_cast<B*>(a2);
21 if(b2 == nullptr){
22 cout<<"b2 nullptr!!"<<endl;
23 }
24
25 B bb;
26 A& a3 = bb;
27 B& b3 = dynamic_cast<B&>(a3);
28 try{
29 A aa;
30 A& a4 = aa;
31 B& b4 = dynamic_cast<B&>(a4);
32 }
33 catch (bad_cast&c){
34 cout<<"bad cast!"<<endl;
35 }
36 return 0;
37 }
- a1指向派生类的基类指针
- a2指向基类的基类指针
- a3指向派生类的基类引用
- a4指向基类的基类引用
将以上都用dynamic转换为派生类的指针或引用,有如下结果:
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIyZuBnL1gzN0MTMwIjMwMzNwkTMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
可见使用指针时,如果无法转型,那么会返回nullptr,使用引用时如果无法转型,会抛出bad_cast异常。
基类无虚函数
将之前的
class A{
virtual void process(){}
};
变为
class A{
void process(){}
};
进行编译出现问题:
编译错误,dynamic_cast的源对象不是多态的。
尾语
对于开头提出的源问题,我想如果我不尝试的话,会说指针返回nullptr,引用抛出bad_cast异常,而不会想到会出现编译错误,这个问题确实很有意思,看来编译器在编译时对dynamic_cast的传入参数做了是否具有运行期信息做了检查。
以上