c++ - 多态 r 值引用?
问题描述
如果我想在一个类中存储一个多态对象,我的第一个想法是这样的:
struct Base {
virtual void print() const {
std::cout << "Base !";
}
};
struct Derived: public Base {
void print() const {
std::cout << "Derived !";
}
};
struct PolymorphicWrapper {
std::unique_ptr<Base> base;
};
问题std::unique_ptr<Base>
在于它会导致复杂的所有权问题和指针语义。虽然引用/原始指针可以具有多态行为,但它们不能绑定到 r 值。
但是我刚刚发现 r 值引用是多态的!
例如:
Base && base = Derived();
base.print(); // Derived !
Base&& base2 = Base();
base2.print(); // Base !
我什至可以在一个类中存储一个 r 值引用!
struct PolymorphicWrapper {
Base&& base;
PolymorphicWrapper(auto iBase) : base(std::move(iBase)) {} // auto to prevent object slicing
};
然而,这似乎好得令人难以置信。我在这里错过了什么吗?这是未定义行为的示例吗?
解决方案
std::move
创建对现有左值的右值引用,这将其明确标记为准备好从中移动。您可以从中初始化另一个右值引用,但是由于两个原因,您不在特殊的生命周期扩展案例中:
它需要一个实际的右值(即一个刚刚在表达式中构造并且从未通过引用传递的对象);
更重要的是,它根本不适用于引用成员。
注意:我有理由确定我做对了,但我似乎找不到标准报价,可能是因为我在聚合初始化和临时实现措辞中迷失了方向。欢迎语言律师。
因此,您只是存储对构造函数参数的引用,该参数在所述构造函数的末尾死亡,并使引用悬空。
请注意,在将任意类型擦除的对象存储为成员时,在一般情况下您无法避免动态分配,如果仅仅是因为动态类型的大小未知且无界。std::unique_ptr
是这种情况下的首选,但如果需要,您也可以设计自己的带有小型对象存储的类型擦除容器。
推荐阅读
- html - 尽管自定义 z-indexes 和 DOM 放置,渐变覆盖文本
- wordpress - 创建一个使用 HTTP API 连接到外部 API 的 WordPress 插件
- python-3.x - 如何使用循环访问句子中动词前面的单词,使用spaCy?Python
- android - Listview 使用 BaseSwipeAdapter 返回错误的位置
- regex - 如何打印与正则表达式匹配的部分 linux 文件名
- php - WooCommerce 不会在发送给客户的电子邮件中显示自定义费用
- javascript - 将值传递给 Json 模式定义
- apache-kafka - 自动更改 kafka 主题分区领导者
- pdf - Magento 2更改pdf文件名
- excel - 使用 api 下载 .xlsx 文件返回 XML 格式的文件?VB.NET