更准确的代码版本是:
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);
这给了我:
“基地功能”
“基地功能”
答案 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();
}
};
感谢你们的答案。