dynamic_cast的好处/用途是什么?

时间:2014-04-14 22:07:45

标签: c++ polymorphism

class Base 
{
        public:
        virtual void print (){cout<<"Base"<<endl;}
};

class Derived :public Base
{
        public:
        virtual void print (){cout<<"Derived"<<endl;}
};

int main(){
        Base *ptrb1=new Base();
        //it will print Base
        ptrb1->print();

        Base *ptrb2=new Derived();
        // it will print Derived
        ptrb2->print();

        Derived *ptrd=NULL;
        //what is the difference between 2ways?
        //what is the benefit of useing dynamic_cast?
        ptrd=dynamic_cast<Derived*>(ptrb2);
        ptrd->print();
}

如果我们可以通过添加虚函数使基类看到派生类的成员并使基本表示从派生类的obj

,那么dynamic_cast的好处(或区别)是什么?

3 个答案:

答案 0 :(得分:4)

如果您不使用强制转换,那么非虚拟成员函数将调用Base方法。以下代码显示了虚拟和非虚函数之间的区别,以及动态转换后发生的情况。

class Base
{
public:
    void print2() {
        cout << "Base" << endl;
    }
    virtual void print() {
        cout << "Base" << endl;
    }
};

class Derived : public Base
{
public:
    void print2() {
        cout << "Derived" << endl;
    }
    virtual void print() {
        cout << "Derived" << endl;
    }
};

int main()
{
    Base* ptrb1 = new Base();
    //it will print Base
    ptrb1->print();
    ptrb1->print2();

    Base* ptrb2 = new Derived();
    // it will print Derived
    ptrb2->print();
    ptrb2->print2();

    Derived* ptrd = NULL;
    //what is the difference between 2ways?
    //what is the benefit of useing dynamic_cast?
    ptrd = dynamic_cast<Derived*>( ptrb2 );
    ptrd->print();
    ptrd->print2();
}

如果您使用static_cast(因为您可能倾向于认为在重新构建指针时可以这样做),那么仍然从Base派生的另一个类将被错误地转换。 dynamic_cast会显示无法转换,然后返回nullptr

答案 1 :(得分:0)

尽可能使用这样的虚拟函数。

使用dynamic_cast if:

  • 你无法找到使用虚拟功能的方法,或
  • 该函数是如此特定于派生类,在基本接口中放置任何内容是没有意义的,或者
  • 你需要弄清楚你的基本指针是否真的是一种特定的派生类型,而不仅仅是要求它做或得到一些东西。

答案 2 :(得分:0)

dynamic_cast根据运行时类型信息提供子类检查,回答问题:

  

是特定派生类型的这个基类对象吗?

如果答案是肯定的(演员成功),那么我们可以使用该对象作为其派生类型,否则我们不能。

如果没有运行时类型信息和dynamic_cast,C ++程序员就必须将他们自己的ad-hoc类型测试结合起来做同样的事情。

为什么你有时想要一个明确的类型检查是需要做一些特定于子类型的小动作,而你不想为了那个小东西引入虚拟方法的繁琐形式。 / p>

static_cast之类的其他强制转型与dynamic_cast的不同之处在于它们不会进行运行时类型检查,并且不会失败:它们会在强制失败时产生虚假结果转换没有意义。