多态性和引用 class 成员 - 调用了错误的虚拟方法

Polymorphism and reference class member - wrong virtual method called

我试图通过创建一个基础 class Document 来理解如何在 C++ 中应用多态性,从中可以得到两个 classes BookNewspaper 是派生的。请注意如何在派生的 classes.

中覆盖虚方法 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 class 与Printer class 聚合(引用),get_content() 适当派生的方法 class根据文档类型调用

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 class 与另一个 class Binding 聚合后,get_content() 似乎并没有再调用右派生的方法class

class Binding {
public:
  Printer m_printer;

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

我不明白为什么下面这段代码...:[=​​31=]

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

...在第三行显示 Binding... NewspaperPrinting 显然正在获取一个 Book 实例作为输入:

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

m_printer 声明为 Binding class 中的引用也不能解决此问题。

据我了解,所讨论的示例应该可以正常工作,并提供类似

的输出
Printing... Book
Printing... Newspaper
Binding... Book
Binding... Newspaper

因为 lifetime extension of a temporary variable.

怀疑编译器中的错误是最后要做的事情,但是...使用的编译器是否正确实现了生命周期延长?

更新:生命周期延长规则不适用于 m_doc class 成员,所以我的猜测是错误的。存在未定义的行为。

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

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

因此,您有悬空引用。在悬空引用上调用方法是未定义的行为

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

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