如何使对象通过RVALUE参考通过而没有复制

How to keep object passed by rvalue reference alive without copy?

本文关键字:复制 RVALUE 何使 对象 参考      更新时间:2023-10-16

我试图将 Child作为r-value传递给 Parent并保存在那里而无需复制 Child

Parent p{ Child{} };
cout << "----Done----" << endl;

现在实现:

class Child
{
public:
    Child() { cout << "Child: created" << endl; }
    ~Child() { cout << "Child: destroyed" << endl; }
};
class Parent
{
    // store as r-value ref
    Child&& child;
public:
    // pass by r-value ref and move
    Parent(Child&& c) :child(move(c))
    {
        cout << "Parent: created" << endl;
    }
    ~Parent() { cout << "Parent: destroyed" << endl; }
};

输出为:

儿童:创建
父:创建
儿童:被摧毁
------完成-------
父母:被摧毁

cppref说: Rvalue references can be used to extend the lifetimes of temporary objects

问题1:为什么Child在末尾没有销毁(或至少在完成完成之后(?
问题2:如何使其寿命更长?

P.S:

Child& child;
...
Parent(Child c) :child(c)

给出完全相同的结果。

cppref说: Rvalue references can be used to extend the lifetimes of temporary objects

您忽略了该报价的重要组成部分。一个更准确的报价是:" RVALUE参考可以用于延长临时对象的寿命"

注意区别?(如果不这样做,请不要担心太多。(有一个链接指向有关如何以及何时可以延长临时寿命的链接。您已经标记了此问题C 11,因此有效的子弹点直到适用C 14:

  • 在构造函数初始化器列表中,临时绑定到参考构件,仅在构造函数退出之前一直存在,直到对象存在为止。(注意:这种初始化是从1696年DR造成的(。

您将临时性绑定到构造函数初始化器列表中的参考成员。临时的寿命不会超出构造函数的尽头。在称为对象的破坏者之前,临时性被摧毁。


如何使其寿命更长?这变得很棘手,但是如果参数始终是暂时的,则可以使您的成员成为非参考,而move参数为成员。如果您想要更灵活的性能,则可能需要接受一些复制。

您引用的标准的一部分是指这样的东西:

struct A { };
int main() {
  const A &a = A{};
  ...
}

,一旦功能范围main结束,现在a将被销毁。这对班级成员不起作用。通过参考将值传递给函数(毕竟所有构造函数只是一个函数(并不是参考的寿命。也不将其分配给成员变量。