指向基类的指针作为重载函数的参数

时间:2014-05-27 22:13:58

标签: c++ overloading

我有以下内容:

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)第二次调用?谢谢!

2 个答案:

答案 0 :(得分:0)

当您使用foo()*bd投放时,bdBase*,就像您已定义它一样:

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

在重载决策中,BaseBase&的匹配比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();