使用static_cast,dynamic_cast或显式转换导出指向Base指针的指针不会调用基函数

时间:2017-09-01 11:50:36

标签: c++ oop dynamic-cast static-cast

我有以下代码。

#include <iostream>
using namespace std;


class Base
{
public:
    virtual int f(){cout<<"Base"<<endl;}
};

class Derived:public Base
{
public:
    int f(){cout<<"Derived"<<endl;}
};

int main()
{
    Base b;
    Derived d;

    b.f(); ///base
    ((Base)d).f(); ///base

    cout<<"----------------"<<endl;

    Base *b1 = new Base;
    Base *b2 = new Derived;
    Derived *d1 = new Derived;

    b1->f(); ///base
    ((Base*)d1)->f(); ///derived
    ((Base*)b2)->f(); ///derived
    static_cast<Base*>(d1);
    d1->f();///derived
    static_cast<Base*>(b2);
    b2->f();///derived

    cout<<"----------------"<<endl;

    Base *b5 = dynamic_cast<Base*>(b2);
    Base *b6 = dynamic_cast<Base*>(d1);
    if(b5)
        b5->f(); ///derived
    if(b6)
        b6->f(); ///derived


    return 0;
}

我想问为什么派生的* d1 OR b2指针在使用显式强制转换(Base ),静态强制转换(static_cast(d1))或动态强制转换(dynamic_cast(d1))转换为基础时)转换后不会调用基类的f()函数。它似乎每次都从派生类调用f()函数。

另外,奇怪的是,当我以这种方式声明对象时。转换工作并调用基本函数。

Base b;
    Derived d;

    b.f(); ///base
    ((Base)d).f(); ///base

现在,我明白从Base类访问f()的正确方法是d->Base::f(),但为什么我应该使用dynamic_cast或static_cast,因为他们不会将派生指针转换为base和调用正确的功能。如果可能的话,我需要详细解释。谢谢!

1 个答案:

答案 0 :(得分:1)

幸运的是,对于你和我的键盘,解释都是微不足道的:

((Base)d) 将对象d切片到值复制的Base实例。

((Base*)d1)->f()仍将调用派生方法,因为Base因此Derived是多态类型,虽然((Base*)d1)Base*指针,但它指向到一个Derived对象。同样适用于static_castdynamic_cast

参考:https://en.wikipedia.org/wiki/Object_slicing