天天看点

dynamic_cast的几种情况本文目的基类有虚函数基类无虚函数尾语

一览

  • 本文目的
  • 基类有虚函数
  • 基类无虚函数
  • 尾语

本文目的

  最近秋招看到一个有意思的问题,对一个没有虚函数的对象使用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 }

           
  1. a1指向派生类的基类指针
  2. a2指向基类的基类指针
  3. a3指向派生类的基类引用
  4. a4指向基类的基类引用

将以上都用dynamic转换为派生类的指针或引用,有如下结果:

dynamic_cast的几种情况本文目的基类有虚函数基类无虚函数尾语

可见使用指针时,如果无法转型,那么会返回nullptr,使用引用时如果无法转型,会抛出bad_cast异常。

基类无虚函数

  将之前的

class A{
    	     virtual void process(){}
     	};
           

变为

class A{
    	     void process(){}
     	};
           

进行编译出现问题:

dynamic_cast的几种情况本文目的基类有虚函数基类无虚函数尾语

编译错误,dynamic_cast的源对象不是多态的。

尾语

  对于开头提出的源问题,我想如果我不尝试的话,会说指针返回nullptr,引用抛出bad_cast异常,而不会想到会出现编译错误,这个问题确实很有意思,看来编译器在编译时对dynamic_cast的传入参数做了是否具有运行期信息做了检查。

以上

继续阅读