【问题标题】:C++ not calling derived class function when passing by const reference通过 const 引用传递时,C++ 不调用派生类函数
【发布时间】:2018-01-23 21:41:40
【问题描述】:

以下是我的代码摘要:

基类:

#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函数时,funcBase版本被调用。

但是,如果我将 main 函数更改为以下内容:

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

funcDerived 版本被正确调用。 我还尝试将 Test 中的 const Base& base 更改为 Base* base。然后使用

构造 Test
Test* t = new Test(new Derivec())

事实证明,funcDerived版本也被正确调用了。

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

谁能解释一下为什么第一个版本没有正确调用派生类方法?

非常感谢您的帮助!

【问题讨论】:

  • 首先,这段代码有未定义的行为。其次,这段代码不应该编译。第三,这段代码在多态类中有非虚析构函数。
  • @SergeyA:不用担心虚拟析构函数,没有delete :-/
  • 对不起!非虚拟析构函数是一个错字...

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


【解决方案1】:

你有一个悬空引用问题。

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

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

因此,您的程序具有未定义的行为。

如果你使用

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

您会得到预期的行为,因为 t 没有悬空引用。


还要注意

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

不应编译,因为 base 是一个参考。这些行必须是:

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

【讨论】:

  • 该代码无法编译。低质量的问题不值得回答!
  • 但这与将 r 值作为对 const 的引用传递本质上是一样的吗?
  • @Guignol,只要你在函数调用内部,引用就有效,在这种情况下是构造函数。函数返回后引用无效。
  • 我现在明白了!非常感谢您的帮助!
猜你喜欢
  • 2014-04-18
  • 2012-06-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多