Pro*_*rof 2 c++ move rvalue-reference c++11
考虑
class X
{
public:
std::unique_ptr<int> m_sp;
A m_a;
A test1()
{
return std::move(m_a);
}
A&& test2()
{
return std::move(m_a);
}
std::unique_ptr<int> test3()
{
return std::move(m_sp);
}
std::unique_ptr<int>&& test4()
{
return std::move(m_sp);
}
std::unique_ptr<int> test5()
{
return std::make_unique<int>(50);
}
};
class A
{
public:
A()
{
m_i = 1;
}
A(A&& other)
{
this->m_i = other.m_i;
other.m_i = -1;
}
A& operator=(A&& other)
{
this->m_i = other.m_i;
other.m_i = -1;
return *this;
}
int m_i;
};
Run Code Online (Sandbox Code Playgroud)
练习这些课程
X x;
A y;
y.m_i = 10;
y = x.test1();
X x2;
A y2;
y2.m_i = 10;
y2 = x2.test2();
Run Code Online (Sandbox Code Playgroud)
两者都调用A的移动赋值,但只有在test1的情况下我们才调用A的移动构造函数.这是为什么?是因为我们不能返回A &&(std :: move会将A转换为A &&,但test1表示它必须返回A).
通常,当想要移动/转移昂贵的成员变量的所有权时,是否要将返回指定为右值引用(A &&)或左值(A)类型?
感觉有点不自然,好像你没有使用成员变量,你让RVO/NRVO做它的事情并且只返回一个左值.考虑到unique_ptr的情况,当你有一个自动变量时,你有一个像test5()这样的签名,但是如果你有一个变量,不适合RVO/NRVO,就像一个成员变量一样,应该首选test3或test4的签名.
有兴趣知道.
谢谢
那里有语义差异.当你返回像中的对象时
A test1()
{
return std::move(m_a);
}
std::unique_ptr<int> test3()
{
return std::move(m_sp);
}
Run Code Online (Sandbox Code Playgroud)
那么你总是离开你的成员.无论来电者是否做了具有返回值的事情,您都会被移出X一个临时的.所有权不再与你同在.调用者可以接管返回值.如果调用者忽略返回值,则临时将被销毁.另一方面,如果你返回rvalue-reference,就像在
A&& test2()
{
return std::move(m_a);
}
std::unique_ptr<int>&& test4()
{
return std::move(m_sp);
}
Run Code Online (Sandbox Code Playgroud)
您只是为调用者提供了移动/接管对象所有权的机会.如果调用者未执行移动,您X将保留所有权,则不会移动该对象.
要理解的关键是,与名称相反,std::move()实际上并没有采取行动.它只允许移动给定的对象.实际移动由相应类型的移动构造函数或移动赋值运算符执行.
所以你的答案是:这取决于你想表达什么.如果你返回一个物体,你会说"如果你想要的话,我就把它扔掉了:它就在那边".如果你返回一个右值参考,你会说"那就是事情,现在你有机会接受它,否则我会保留它"......
| 归档时间: |
|
| 查看次数: |
104 次 |
| 最近记录: |