关于虚拟方法的问题

时间:2010-05-05 21:05:50

标签: c++ methods virtual-functions

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

5 个答案:

答案 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();