6

static_cast与dynamic_cast到底是什么? - Ann-

 1 week ago
source link: https://www.cnblogs.com/pkuqcy/p/18153681
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

static_cast与dynamic_cast到底是什么?

写这个随笔说一下C++的static_cast和dynamic_cast用在子类与父类的指针转换时的一些事宜。首先,【static_cast,dynamic_cast】【父类指针,子类指针】,两两一组,共有4种组合:用 static_cast 父类转子类、用 static_cast 子类转父类、使用 dynamic_cast 父类转子类、用 dynamic_cast 子类转父类。搞清楚了这4种情况,这篇文章的任务也就达成了。

先说结论,后面给出一个作者觉得通俗易懂的理解:

1. static_cast : 父类转子类:可以转,不报错,不安全;

2.static_casrt : 子类转父类:可以转,不报错,安全;

3.dynamic_cast : 父类转子类 :

  a)若父类中没有虚函数,不能转,编译报错;

  b)若父类至少有一个虚函数则可以转,不报错;但:

    b.1)若父类指针指向的确实是一个子类对象,则dynamic_cast返回该子类对象的地址;

    b.2)若父类指针指向的是父类对象,则dynamic_cast返回空指针nullptr;

 4.dynamic_cast:子类转父类:可以转,不报错,安全。

总体来看,子类指针父类指针无论怎样都是安全、允许的(上面的2、4),所以static_cast和dynamic_cast都可以安全使用。

再说上面的1、3。 其实,static_cast相当于我们程序员对编译器的一种承诺:我们清楚地知道这样转存在的任何风险,并且我们能够接受这样的风险。所以,当我们用static_cast将父类指针转换成子类指针时,编译器不报错。而dynamic_cast是在运行时执行类型转换,用于将基类的指针安全地转换成派生类的指针,也就是说,dynamic_cast会进行动态类型检查。dynamic_cast相当于给程序员提供了一种安全的机制,让程序员能够安全地使用父类指针的动态类型。

下面举一个使用dynamic_cast(以上3中的b)的例子。首先给出父类和子类的定义:

class B
{
public:
    virtual ~B() {};
};

class D : public B
{

};

若有以上类的定义:

B* pb = new B;
if( D* p3 = dynamic_cast<D*>(pb) )   
{
    cout << "成功了" << endl;
  //若程序到此处,则程序员知道,pb指向的实际上是子类对象,可以使用p3
}
else {
    cout << "失败了" << endl;
  //若程序到此处,则程序员知道,pb指向的实际上是父类对象,使用pb
}

输出:失败了。因为动态运行时,pb指向的是父类,并不是子类。

B* pb = new D;
if( D* p3 = dynamic_cast<D*>(pb) )   
{
    cout << "成功了" << endl;
  //若程序到此处,则程序员知道,pb指向的实际上是子类对象,可以使用p3
}
else {
    cout << "失败了" << endl;
  //若程序到此处,则程序员知道,pb指向的实际上是父类对象,使用pb
}

输出:成功了。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK