C ++在传递const引用时不调用派生类函数

时间:2017-08-15 21:26:52

标签: c++ c++11 inheritance polymorphism virtual-functions

以下是我的代码的摘要:

基类:

#include <iostream>
using namespace std;
class Base {
public:
    Base() { cout << "Base constructor" << endl; }
    ~Base() { cout << "Base destructor" << endl; }
    virtual void func(void) const { cout << "base" << endl; }
};

派生类:

#include "Base.h"
class Derived : public Base {
public:
    Derived() { cout << "Derived constructor" << endl; }
    ~Derived() { cout << "Derived destructor" << endl; }
    void func(void) const { cout << "derived" << endl; }
};

测试类:

#include "Derived.h"

class Test {
public:
    const Base& base;
    Test(const Base& _base) : base(_base) { cout << "Test constructor" << endl; }
    void test() { base->func(); }
    ~Test() { cout << "Test destructor" << endl; }
};

测试的主要功能:

#include "Test.h"
int main(void) {
    Test* t = new Test(Derived());
    t->test();
    return 0;
}

当我运行main函数时,正在调用 func Base 版本。

但是,如果我将主要功能更改为以下内容:

#include "Test.h"
int main(void) {
    Derived d;
    Test* t = new Test(d);
    t->test();
    return 0;
}

正确调用 func 派生版本。 我还试图改变 const Base&amp; 测试 Base * base 的基础。然后使用

构建测试
Test* t = new Test(new Derivec())

事实证明 func 派生版本也被正确调用。

我在想,如果我使用引用或指针,那么多态就会起作用。

有人可以向我解释为什么第一个版本没有正确调用派生类方法吗?

非常感谢你的帮助!

1 个答案:

答案 0 :(得分:2)

你有一个悬空参考问题。

Test* t = new Test(Derived());

您正在使用Derived类型的临时对象来构建t。在Test的构造函数返回后,临时对象被删除。

因此,您的程序有不确定的行为。

如果您使用

Derived d;
Test* t = new Test(d);

您获得了预期的行为,因为t没有悬空参考。

另请注意

void test() { base->func(); }

不应该编译,因为base是一个引用。那条线必须是:

void test() { base.func(); }