如果两个方法都声明为虚拟,那么被调用的Method1()的两个实例不应该是派生类的Method1()吗?
我看到BASE然后每次调用DERIVED。我正在为面试做一些评论,我想确保我有这个直接。的xD
class BaseClass
{
public:
virtual void Method1() { cout << "Method 1 BASE" << endl; }
};
class DerClass: public BaseClass
{
public:
virtual void Method1() { cout << "Method 1 DERVIED" << endl; }
};
DerClass myClass;
((BaseClass)myClass).Method1();
myClass.Method1();
方法1 BASE
方法1 DERVIED
答案 0 :(得分:14)
不,“C风格”演员((BaseClass)myClass)
通过切片 myClass创建一个临时BaseClass
对象。它的动态类型为BaseClass
,它根本不是DerClass
,因此被调用的Method1
是基类方法。
myClass.Method1()
是直接电话。由于myClass
是一个对象,而不是一个引用,因此没有虚拟分派(没有必要)。
答案 1 :(得分:12)
不,因为虚函数机制仅在通过指针或引用调用函数时才有效。否则,对象的静态类型用于确定要调用的函数。
答案 2 :(得分:6)
您在此处看到的内容称为"slicing"。将派生类的对象强制转换为基类“切掉”不在基类中的所有内容。
在C ++中,虚函数仅适用于指针或引用。为了使您的示例正常工作,您必须执行以下操作:
DerClass myClass;
((BaseClass *) &myClass)->Method1();
或者你可以做到
BaseClass *pBase = new DerClass;
pBase->Method1();
答案 3 :(得分:5)
因为广告((BaseClass)myClass)
将myClass
对象从DerClass
切换为BaseClass
,所以只有BaseClass
的{{1}}实现是调用。
要使多态性正常工作,必须通过指针调用方法:
Method1()
或引用:
DerClass myClass;
BaseClass* ptrToMyClass = &myClass;
ptrToMyClass->Method1(); // Calls the DerClass implementation of Method1()
答案 4 :(得分:0)
((BaseClass的)MyClass的).Method1(); - &GT;对象切片因此总是会调用基类方法。 真正的多态行为是通过基类指针实现的,基类指针可以包含派生类的任何对象。 因此,要实现您想要的,您需要传递派生类对象的地址并将其指定为基类指针。如下: ((BaseClass *)&amp; myClass) - &gt; Method1();