开发者

overriden virtual function is not getting called

开发者 https://www.devze.com 2022-12-20 19:56 出处:网络
a more exact version of the code is: class SomeParam; class IBase { public: virtual void Func(SomeParam* param = NULL)

a more exact version of the code is:

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开发者_JAVA技巧 = new DerivedB;
FuncCaller(a,b);

This gives me:

"Base func"

"Base func"


It looks like you have provided a simplified version of your code to make it more readable, but you have oversimplified inadvertently.

The most likely reasons for your behaviour are:

  • Slicing in FuncCaller() (see quamrana's answer for the details)
  • Wrong overriding, such as making the derived class function const, while the base class function is not const

EDIT: After reading the edited question, it is clearly the second reason. You are not overriding the base class function, but hiding it in the derived classes with a new definition. You need to keep exactly the same signature (covariance does not apply here, since the function returns void) in the derived classes. In code, you need to do either:

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);

or

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);


I found the reason:
The overriden virtual functions also must have a default parameter like Base's.like:

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

Thanks for the answers guys.


Your virtual function is not overridden.

Your supposedly "virtual" methods in the derived classes have different signatures. The method in the base class has one parameter, while the methods in the derived classes have no parameters. Because of this, the methods in the derived classes are completely unrelated to the base class method. They don't override the base class method. This is why the base class method is always called.


I've tried a copy of the code you posted on VS2008 and it works fine.

I can only suggest that your actual code is more like:

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

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

where FuncCaller slices the base part off the derived instances.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号