c ++ 11:如何理解函数移动

时间:2016-03-15 04:19:44

标签: c++11 move

我无法理解c ++ 11中的函数移动。

here开始,我得到了以下内容:

  

虽然注意到 - 在标准库中 - 移动意味着   move-from对象保持有效但未指定的状态。哪一个   意味着,在这样的操作之后,移动的值   对象应仅被销毁或分配新值;访问它   否则产生一个未指定的值。

在我看来,在move()之后,移动的对象已经“清晰”了。但是,我在下面做了一个测试:

std::string str = "abcd";
std::move(str);
std::cout<<str;

我的屏幕上显示abcd str被摧毁了吗?如果是这样,我可以得到abcd,因为我很幸运?或者我误解了函数move

此外,当我阅读 C ++ Primer 时,我得到了这样的代码:

class Base{/* ... */};
class D: public Base{
public:
    D(D&& d): Base(std::move(d)){/* use d to initialize the members of D */}
};
我现在很困惑。如果函数move将清除对象,则参数d将清除,我们如何“使用d来初始化D的成员”?

2 个答案:

答案 0 :(得分:4)

std::move实际上并没有任何事情。它大致类似于强制转换表达式,因为返回值是原始对象,但处理方式不同。

更准确地说,std::move以一种形式返回对象,该形式可以使其资源因某些其他目的而“被盗”。原始对象或多或少仍然有效(你只应该为它做一些特殊的事情,尽管这主要是约定问题而不一定适用于非标准库对象),但被偷走的资源没有更长的属于它,并且通常不再被它引用。

但是! std::move本身并没有偷窃。它只是为偷窃而设置的东西。既然你没有对结果做任何事情,更不用说可以利用这个机会的东西了,没有什么东西被偷走了。

答案 1 :(得分:1)

std :: move不会移动任何东西。 std :: move只是一个执行强制转换的函数模板。 std :: move无条件地将其参数强制转换为右值,

std::move(str);

使用此表达式,您只需从左值到右值进行类型转换。

程序中的小修改以便更好地理解。

 std::string str = "abcd";
 std::string str1 = std::move(str);
 std::cout<<str<<std::endl;
 std::cout<<str1<<std::endl; 

strstd::movestd::string = std::move(str); =&gt;左右对左值进行类型转换:此表达式调用实际窃取资源的string move constructorstr资源(abcd)被打磨并打印出空字符串。

以下是移动功能的示例实现。请注意,它不是标准库的完整实现。

template<typename T> // C++14; still in
decltype(auto) move(T&& param) // namespace std
{
using ReturnType = remove_reference_t<T>&&;
return static_cast<ReturnType>(param);
}

将std :: move应用于对象会告诉编译器该对象是否有资格从中移动。它投向了右值。

class Base{/* ... */};
class D: public Base{
public:
    D(D&& d): Base(std::move(d)){/* use d to initialize the members of D */}
};

Base(std::move(d))它只会向上移动基类部分。

这里有一件有趣的事要向你学习。如果不使用std::move D(D&& d): Base(d)来调用基类析构函数,那么d将被视为左值的左值和复制构造函数,而不是移动构造函数。有关详细信息,请参阅Move constructor on derived object