更精确的代码版本是:
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);
这给了我:
"Base func"
"Base func"
发布于 2010-02-23 11:37:37
看起来您提供了代码的简化版本,以使其更具可读性,但您无意中过度简化了。
你的行为最有可能的原因是:
在FuncCaller()
中的
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);
发布于 2010-02-23 19:02:59
您的虚拟函数未被重写。
您在派生类中假定的“虚”方法具有不同的签名。基类中的方法有一个参数,而派生类中的方法没有参数。因此,派生类中的方法与基类方法完全无关。它们不会覆盖基类方法。这就是基类方法总是被调用的原因。
发布于 2010-02-23 11:20:21
我已经尝试了你在VS2008上发布的代码副本,它工作得很好。
我只能建议您的实际代码更类似于:
void FuncCaller(IBase instance)
{
instance.Func();
}
void Funcs()
{
DerivedA *a = new DerivedA;
DerivedB *b = new DerivedB;
FuncCaller(*a);
FuncCaller(*b);
}
其中,FuncCaller
将基础零件从衍生实例中切片。
https://stackoverflow.com/questions/2317559
复制相似问题