[英]Polymorphic r-value references?
如果我想在 class 中存储多态 object,我的第一个想法是类似于以下内容:
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
创建一个对现有左值的右值引用,这明确地将其标记为准备好从中移动。 您可以从中初始化另一个右值引用,但是由于两个原因,您不在特殊的生命周期扩展案例中:
它需要一个实际的右值(即一个 object,它只是在表达式中构建并且从未通过引用传递);
更重要的是,它根本不适用于引用成员。
注意:我有理由确定我做对了,但我似乎找不到标准报价,可能是因为我在聚合初始化和临时实现措辞中迷失了方向。 欢迎语言律师。
因此,您只是存储对构造函数参数的引用,该参数在所述构造函数的末尾死亡,并使引用悬空。
请注意,当存储任意类型擦除的 object 作为成员时,您无法在一般情况下避免动态分配,如果仅仅是因为动态类型的大小未知且无界。 std::unique_ptr
是这种情况下的首选,但如果您愿意,您也可以设计自己的类型擦除容器和小型 object 存储。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.