我有以下代码 .
#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 回答
幸运的是,对于你和我的键盘,解释是微不足道的:
((Base)d)
将对象d
切片为值复制的Base
实例 .((Base*)d1)->f()
仍将调用派生方法,因为Base
因此Derived
是多态类型,虽然((Base*)d1)
是Base*
指针,但它指向Derived
对象 . 同上static_cast
和dynamic_cast
.参考:https://en.wikipedia.org/wiki/Object_slicing