我测试了以下代码:
#include <iostream>
using namespace std;
class foo{
public:
foo() {cout<<"foo()"<<endl;}
~foo() {cout<<"~foo()"<<endl;}
};
int main()
{
foo f;
move(f);
cout<<"statement \"move(f);\" done."<<endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出是:
foo()
statement "move(f);" done.
~foo()
Run Code Online (Sandbox Code Playgroud)
但是,我预计:
foo()
~foo()
statement "move(f);" done.
Run Code Online (Sandbox Code Playgroud)
根据函数移动的源代码:
template<typename _Tp>
constexpr typename std::remove_reference<_Tp>::type&&
move(_Tp&& __t) noexcept
{ return static_cast<typename std::remove_reference<_Tp>::type&&>(__t); }
Run Code Online (Sandbox Code Playgroud)
返回的对象是一个正确的值,那么为什么不立即销毁呢?
-------------------------------------------------- ---------------
我想我只是混淆了rvalue和rvalue引用.
我修改了我的代码:
#include <iostream>
template<typename _Tp>
constexpr typename /**/std::remove_reference<_Tp>::type /* no && */
/**/ mymove /**/ (_Tp&& __t) noexcept
{ return static_cast<typename std::remove_reference<_Tp>::type&&>(__t); }
using namespace std;
class foo{
public:
foo() {cout<<"foo() at "<<this<<endl;} /* use address to trace different objects */
~foo() {cout<<"~foo() at "<<this<<endl;} /* use address to trace different objects */
};
int main()
{
foo f;
mymove(f);
cout<<"statement \"mymove(f);\" done."<<endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
现在我得到了我一直期待的东西:
foo() at 0x22fefe
~foo() at 0x22feff
statement "mymove(f);" done.
~foo() at 0x22fefe
Run Code Online (Sandbox Code Playgroud)
Ste*_*sop 14
从对象移动不会改变其生命周期,只会改变其当前值.您的对象foo
在返回时被销毁main
,这是在您的输出之后.
此外,std::move
不会离开对象.它只返回一个rvalue引用,其引用是对象,可以从对象移动.
当对象超出范围时会被破坏.从物体移动不会改变这一点; 根据移动构造函数或移动赋值操作符的作用,移动后对象的状态可能不同,但尚未被销毁,因此实际的规则是从对象移动必须使其保持在可以被摧毁.
除此之外,正如@ R.MartinhoFernandes指出的那样,std::move
没有做任何事情.它是对象的移动构造函数或移动赋值运算符,它执行任何需要完成的操作,并且不会在调用中应用std::move
; 当移动的对象用于构造新对象(移动构造函数)或分配给现有对象(移动赋值运算符)时应用它.像这样:
foo f;
foo f1(f); // applies foo's copy constructor
foo f2(std::move(f)); // applies foo's move constructor
foo f3, f4;
f3 = f; // applies foo's copy assignment operator
f4 = std::move(f1); // applies foo's move assignment operator
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
1778 次 |
最近记录: |