覆盖虚函数未被调用

时间:2010-02-23 11:10:29

标签: c++ inheritance function virtual

更准确的代码版本是:

class SomeParam;
class IBase
{
public:
    virtual void Func(SomeParam* param = NULL)
    {
        cout << "Base func";
    }
};

class DerivedA : public IBase
{
public:
    void Func()
    {
        //do some custom stuff
        cout << "DerivedA func";
        IBase::Func();
    }
};

class DerivedB : public IBase
{
public:
    void Func()
    {
        //do some custom stuff
        cout << "DerivedB func";
        IBase::Func();
    }
};

//at somewhere else
void FuncCaller(IBase *instance1, IBase *instance2)
{
    IBase *i1 = instance1;
    IBase *i2 = instance2;
    i1->Func();
    i2->Func();
}

DerivedA *a = new DerivedA;
DerivedB *b = new DerivedB;
FuncCaller(a,b);

这给了我:
    “基地功能”
    “基地功能”

4 个答案:

答案 0 :(得分:9)

看起来您提供了代码的简化版本以使其更具可读性,但您无意中过度简化了。

您行为的最可能原因是:

  • 切入FuncCaller()(详见quamrana的答案)
  • 错误的覆盖,例如创建派生类函数const,而基类函数不是const
编辑:阅读编辑过的问题后,显然是第二个原因。您没有覆盖基类函数,而是使用新定义将其隐藏在派生类中。您需要在派生类中保持完全相同的签名(协方差不适用于此处,因为函数返回void)。在代码中,您需要执行以下任一操作:

class SomeParam;
class IBase
{
public:
    virtual void Func(SomeParam* param = NULL)
    {
        cout << "Base func";
    }
};

class DerivedA : public IBase
{
public:
    void Func(SomeParam* param = NULL)
    {
        //do some custom stuff
        cout << "DerivedA func";
        IBase::Func();
    }
};

class DerivedB : public IBase
{
public:
    void Func(SomeParam* param = NULL)
    {
        //do some custom stuff
        cout << "DerivedB func";
        IBase::Func();
    }
};

//at somewhere else
void FuncCaller(IBase *instance1, IBase *instance2)
{
    IBase *i1 = instance1;
    IBase *i2 = instance2;
    i1->Func();
    i2->Func();
}

DerivedA *a = new DerivedA;
DerivedB *b = new DerivedB;
FuncCaller(a,b);

class SomeParam;
class IBase
{
public:
    virtual void Func()
    {
        cout << "Base func";
    }
};

class DerivedA : public IBase
{
public:
    void Func()
    {
        //do some custom stuff
        cout << "DerivedA func";
        IBase::Func();
    }
};

class DerivedB : public IBase
{
public:
    void Func()
    {
        //do some custom stuff
        cout << "DerivedB func";
        IBase::Func();
    }
};

//at somewhere else
void FuncCaller(IBase *instance1, IBase *instance2)
{
    IBase *i1 = instance1;
    IBase *i2 = instance2;
    i1->Func();
    i2->Func();
}

DerivedA *a = new DerivedA;
DerivedB *b = new DerivedB;
FuncCaller(a,b);

答案 1 :(得分:2)

您的虚拟功能未被覆盖。

派生类中所谓的“虚拟”方法具有不同的签名。基类中的方法有一个参数,而派生类中的方法没有参数。因此,派生类中的方法与基类方法完全无关。它们不会覆盖基类方法。这就是始终调用基类方法的原因。

答案 2 :(得分:1)

我已经尝试过你在VS2008上发布的代码副本,但它运行正常。

我只能建议您的实际代码更像:

void FuncCaller(IBase instance)
{
    instance.Func();
}

void Funcs()
{
DerivedA *a = new DerivedA;
DerivedB *b = new DerivedB;
FuncCaller(*a);
FuncCaller(*b);
}

其中FuncCaller将基础部分从派生实例中分离出来。

答案 3 :(得分:1)

我找到了原因:
覆盖虚函数也必须具有默认参数,如Base's.like:

class DerivedB : public IBase
{
public:
    void Func(SomeParam* param=NULL)
    {
        //do some custom stuff
        cout << "DerivedB func";
        IBase::Func();
    }
};

感谢你们的答案。