4

如果这两个方法都被声明为虚拟的,那么被调用的 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 基础
方法 1 衍生

4

5 回答 5

14

不,“C 风格”演员通过切片myClass((BaseClass)myClass)创建一个临时BaseClass对象。它的动态类型是,它根本不是 a所以被调用的是基类方法。BaseClassDerClassMethod1

myClass.Method1()是直接调用。作为myClass一个对象,而不是引用,没有虚拟调度(没有必要)。

于 2010-05-05T21:10:35.807 回答
12

不,因为虚函数机制仅在通过指针或引用调用函数时才有效。否则使用对象的静态类型来确定调用哪个函数。

于 2010-05-05T21:08:22.767 回答
6

您在这里看到的称为“切片”。将派生类的对象转换为基类会“切掉”不在基类中的所有内容。

在 C++ 中,虚函数仅适用于指针或引用。为了使您的示例正常工作,您必须执行以下操作:


DerClass myClass;
((BaseClass *) &myClass)->Method1();

或者你可以做


BaseClass *pBase = new DerClass;
pBase->Method1();

于 2010-05-05T21:49:11.123 回答
5

因为 cast将对象从to((BaseClass)myClass)切片,所以只调用' 的实现。myClassDerClassBaseClassBaseClassMethod1()

为了使多态性正常工作,您必须通过指针调用方法:

DerClass myClass; 
BaseClass* ptrToMyClass = &myClass;
ptrToMyClass->Method1(); // Calls the DerClass implementation of Method1()

或参考:

DerClass myClass; 
BaseClass& refToMyClass = myClass;
refToMyClass.Method1();  // Calls the DerClass implementation of Method1()
于 2010-05-05T21:09:36.217 回答
0

((BaseClass)myClass).Method1(); --> 对象切片因此总是会调用基类方法。真正的多态行为是通过基类指针实现的,基类指针可以包含派生类的任何对象。因此,要实现您想要的,您需要传递派生类对象的地址并将其类型化为基类指针。如下: ((BaseClass *) &myClass)->Method1();

于 2015-01-29T09:13:04.913 回答