关于static_cast与danymic_cast的终极解析

来源:互联网 发布:洛丹伦的夏天 知乎 编辑:程序博客网 时间:2024/05/20 08:27

 

关于static_cast和dynamic_cast:

1,附详细代码并解释,总算搞清楚了!

class base{
 public:
  virtual void foo(){}//用于添加虚函数表vtable
  int a;
};
class left_hand:public base{
};
class right_hand:public base{
};
class derive:public left_hand,public right_hand{
};

class unrelated{//一个毫不相关的类
 public:
  virtual void Foo(){}
};

void main()
{
left_hand* pl = new derive;
base* pb = pl;//隐式类型转换,可以用static_cast代替,无区别,安全的转换
derive* pd = dynamic_cast<derive*>(pl);//这里会给出警告,若用static_cast可

                                                           //编译成功,因为2指针存在继承关系,运行
right_hand* pr = new derive;                 //也能成功,因为pl确实指向的是derive
pd = static_cast<derive*>(pr);              //这里用于测试多个基类的无差异性
right_hand* pr2 = new right_hand;        //注意这里,pr2指向的不是derive
pd = dynamic_cast<derive*>(pr);          //这里不管用static_cast还是dynamic_cast
delete pl;                                             //都能编译成功,但运行时,若用static_cast
delete pr;                                            //极有可能使程序崩溃,用dynamic_cast则造 
delete pr2;                                          //成pd为NULL,慎用!

unrelated* unr;
pd = dynamic_cast<derive*>(unr);//only warning:C4541
left_hand* lh;
right_hand* rh;
lh = static_cast<left_hand*>(rh);//compiling time check,errorC2440
lh = dynamic_cast<left_hand*>(rh);//only warning:C4541

//if:

left_hand* lh2 = new derive;
right_hand* rh2;

rh2 = dynamic_cast<left_hand*>(lh2);//运行时也能成功转换

delete lh2;
}

static_cast<type>(expression)用于一般转换,代替隐式类型转换,以及基类指针到子类指针转换,只进行编译器检查(只要两个指针存在public继承关系,编译均能成功,而不管指针指向的确切类型),但在运行时有可能发生错误(当基类指针指向的确实不是要转换为的子类时),造成程序崩溃;dynamic_cast<type>(expression)用于基类到子类指针的转换,dynamic_cast只进行运行时检查(通过vtable获得运行时类型信息,这就是必须要有虚函数的原因),如果指针指向的确切类型可以转换(如基类ptr确实指向要转换的子类,或者子类的派生类),则转换成功,否则返回NULL.所以在进行dynamic_cast转换时最好加上异常处理或者判断指针是否为NULL的语句。

原创粉丝点击