2017-09-01 52 views
1

我有以下代码。使用static_cast,dynamic_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或B2指针时使用显式类型转换(基地),静态浇铸(的static_cast(D1))或动态转换转换成基(dynamic_cast的(D1))转换后不会调用基类的f()函数。它似乎每次都从派生类调用f()函数。

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

Base b; 
    Derived d; 

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

现在,我明白了正确的方式来访问从基类中的F()是d->Base::f(),但我为什么要使用dynamic_cast的或的static_cast,因为他们不会转换得到的指针基地,并调用正确的功能。如果可能,我需要详细的解释。谢谢!

+1

'dynamic_cast'用于铸造碱衍生,这可能会失败。派生到基地总是工作,并且不需要施放。 –

+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

相关问题