首页 > 解决方案 > 多态性和引用类成员 - 调用了错误的虚拟方法

问题描述

我试图通过创建一个基类来了解如何在 C++ 中应用多态性,Document这两个类BookNewspaper派生自该基类。注意虚拟方法get_content()是如何在派生类中被覆盖的。

class Document {
public:
  virtual std::string get_content() const { return ""; }
};

class Book : public Document {
public:
  std::string get_content() const override { return "Book"; }
};

class Newspaper: public Document {
public:
  std::string get_content() const override { return "Newspaper"; }
};

类与Document类聚合Printer(通过引用),get_content()根据文档类型调用相应派生类的方法。

class Printer {
public:
  const Document& m_doc;

  Printer(const Document& doc): m_doc(doc) {
    std::cout << "Printing... " << m_doc.get_content() << std::endl;
  }

  std::string get_content() const { return m_doc.get_content(); }
};

到目前为止,一切正常,但是一旦我将该Printer类与另一个类聚合Bindingget_content()似乎不再调用正确派生类的方法。

class Binding {
public:
  Printer m_printer;

  Binding(const Printer& printer): m_printer(printer) {
    std::cout << "Binding... " << m_printer.get_content() << std::endl;
  }
};

我不明白为什么下面的代码...:

int main() {
  Printer p1(Book{});
  Printer p2(Newspaper{});
  Binding b1(p1);
  Binding b2(p2);
}

...显示Binding... Newspaper在第三行,而Printing显然将Book实例作为输入:

Printing... Book
Printing... Newspaper
Binding... Newspaper
Binding... Newspaper

在类中m_printer声明为引用Binding也不能解决这个问题。

标签: c++referencepolymorphism

解决方案


Printer p1(Book{});
Printer p2(Newspaper{});

在这里,您正在使用临时对象。这些对象在创建它们的语句结束时被销毁。

所以,你有悬空的参考。对悬空引用调用方法是未定义的行为

在 C++ 中,您负责对象的生命周期。

(参考寿命延长不适用于此处)


推荐阅读