由右值引用绑定的自定义类的右值的生命周期

问题描述 投票:0回答:2
#include <iostream>

using namespace std;

class Someclass
{
    public:
    
    ~Someclass()
    {
        cout << "Someclass Dtor called" << endl;
    }
};

int main()
{
    Someclass obj;
    
    {
        Someclass&& ref = move(obj);
    }

    // At this point why the dtor is not called ? Because the reference went out of scope
    
    cout << "Ending program" << endl;
    
    return 0;
}

上面的代码输出如下:

节目结束

某个班主任打来电话

但是我的疑问是为什么输出不是这个?

某个班主任打来电话

节目结束

当引用超出范围时,不应该调用Someclass的dtor吗?

c++ move rvalue-reference
2个回答
1
投票

为什么输出不是这个?

因为没有发生移动操作(移动构造/赋值)。在您的示例中,因为

ref
是右值引用。基本上,
std::move(obj)
只是给出一个 xvalue,然后将其限制为右值引用
ref

ref
仍然只是实际对象
obj
的别名,其生命周期仅在
}
main
之后结束。


如果您要从

&&
中删除
ref
,那么您将观察到预期的输出,因为在这种情况下确实会发生移动操作:

{
//-----------vv----------------> && removed from here
    Someclass ref = move(obj);
}

上述修改后的程序的输出将是:

Someclass Dtor called
Ending program
Someclass Dtor called

演示


1
投票

当引用超出范围时,不应该调用

Someclass
的 dtor 吗?

不。引用是现有对象的别名或替代名称。它提供了一种通过另一个名称访问对象的方法。它不拥有您案例中的对象。

因此当这一行:

{
    Someclass&& ref = move(obj);
}

rvalue

ref
超出范围,唯一的别名是超出范围,而不是实际对象。

实际对象

obj
main()
末尾超出范围。于是就有了这样的结果。


但是,(如@HolyBlackCat提到的)引用可以拥有一个生命周期延长的对象。

在下文中,临时对象在传递给具有给定引用的函数时获得延长的生命周期,并且它们也拥有临时对象。

void foo(const Someclass&) {}
void boo(Someclass&&) {}
void bar(const Someclass&&) {}

foo(Someclass{});
boo(Someclass{});
bar(Someclass{});
© www.soinside.com 2019 - 2024. All rights reserved.