#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吗?
为什么输出不是这个?
因为没有发生移动操作(移动构造/赋值)。在您的示例中,因为
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
当引用超出范围时,不应该调用
的 dtor 吗?Someclass
不。引用是现有对象的别名或替代名称。它提供了一种通过另一个名称访问对象的方法。它不拥有您案例中的对象。
因此当这一行:
{
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{});