c++ - 多态性和引用类成员 - 调用了错误的虚拟方法
问题描述
我试图通过创建一个基类来了解如何在 C++ 中应用多态性,Document
这两个类Book
和Newspaper
派生自该基类。注意虚拟方法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
类与另一个类聚合Binding
,get_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
也不能解决这个问题。
解决方案
Printer p1(Book{});
Printer p2(Newspaper{});
在这里,您正在使用临时对象。这些对象在创建它们的语句结束时被销毁。
所以,你有悬空的参考。对悬空引用调用方法是未定义的行为。
在 C++ 中,您负责对象的生命周期。
(参考寿命延长不适用于此处)
推荐阅读
- c# - 使用 .net core 将 Html 转换为纯文本
- npm - Webpack 插件:如何在构建时读取插件使用者的文件?
- javascript - 画布:在整个画布上创建半透明覆盖,除了一个窗口
- javascript - 正则表达式从开始查找字符串
- huggingface-transformers - 减少 XLTransformers 的输出层大小
- java - 春天,休眠:java.sql.SQLSyntaxErrorException:表'test2.ciudad_persona'不存在
- sorting - 排序层完全没有效果
- php - 你如何在 PhpStorm 上使用 file_get_contents()?
- python - 我正在尝试用不同类型的水果训练我的模型
- arcgis-js-api - 使用 wkid 102704 时,ArcGIS 地图显示所有大陆(完全缩小)