我有以下内容:
class Base {};
class Derived : public Base {};
void foo(Base const &b) { cout << "foo(Base)" << endl; }
void foo(Derived const &d) { cout << "foo(Derived)" << endl; }
/* ... */
Base *bb = new Base();
Base *bd = new Derived();
Derived *dd = new Derived();
foo(*bb);
foo(*bd); // <== calling foo(Base const &)
foo(*dd);
程序输出foo(Base),foo(Base)和foo(Derived)。为什么foo(Base)
第二次被召唤?如何重写这个,让foo(Derived)
第二次调用?谢谢!
答案 0 :(得分:0)
当您使用foo()
向*bd
投放时,bd
为Base*
,就像您已定义它一样:
Base *bd =...
相应地,编译器调用void foo(Base const&)
。
如果您确定可以进行向下转发,可以拨打static_cast<>()
:
foo( * static_cast<Derived*>(bd) );
我觉得这很难看。
你可以简单地使用覆盖。
struct Base
{
virtual void foo(){ std::cout << "only base and derived classes that don't overide foo"; }
virtual ~Base(){};
};
struct MyDerived : public Base
{
virtual void foo(){ std::cout << "only MyDerived calls this function"; }
};
void test()
{
Base b;
MyDerived d;
b.foo(); // prints: only base and derived that don't overide foo
d.foo(); // prints: only MyDerived calls this function
}
答案 1 :(得分:0)
在重载决策中,Base
与Base&
的匹配比notBase&
更好。
您似乎想要多态行为,因此您必须通过包含至少一个虚函数来使您的类具有多态性。 (这可能是析构函数)。
多态性也不会影响重载决策。要获得多态行为,您必须通过virtual
函数或dynamic_cast
。
一个选项(不是很好,但有可能)是用以下方式打开foo
:
void foo(Base const &b)
{
Derived const *d = dynamic_cast<Derived const *>(&b);
if ( d ) { foo(*d); return; }
由R Sahu链接的引擎是一个概括,你注册各种派生类,以避免有大量的copypasta。
然而,使用虚拟功能被认为是更好的风格。如果您不想将foo
更改为只是一个以多态方式调用Base
的函数,那么执行此操作的一种方法是:
void foo(struct Base const &b);
void foo(struct Derived const &d);
struct Base
{
virtual void foo_caller() const { foo(*this); }
// ...
};
struct Derived
{
virtual void foo_caller() const { foo(*this); }
// ...
};
int main()
{
Base *p = new Derived();
p->foo_caller();