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

c++11: how to understand the function move

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

来自 here,我得到以下信息:

Although note that -in the standard library- moving implies that the moved-from object is left in a valid but unspecified state. Which means that, after such an operation, the value of the moved-from object should only be destroyed or assigned a new value; accessing it otherwise yields an unspecified value.

在我看来,在move()之后,被移出的对象是"clear"。但是,我在下面做了一个测试:

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就会清空,我们怎么会"use d to initialize the members of D"?

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

更准确地说,std::move return 对象的形式可以使其资源 'stolen' 用于其他目的。原始对象或多或少仍然有效(你只应该对它做一些特殊的事情,虽然这主要是一个约定问题,不一定适用于非标准库对象),但被偷走的资源没有不再属于它,一般不会再被它引用。

但是! std::move 本身并不会偷窃。它只是设置允许偷窃的东西。由于您没有对结果做任何事情,更不用说可以利用这个机会的事情了,所以没有任何东西被盗。

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); 将左值类型转换为右值 => 此表达式调用 string move constructor 实际发生资源窃取的位置。 str 资源(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)) 它只会向上转换只移动基础 class 部分。

这里还有一件有趣的事情要为你学习。如果你不使用 std::move 调用 base class 析构函数,比如 D(D&& d): Base(d) 那么 d 将被视为左值,并且涉及 Base class 的复制构造函数而不是移动构造函数。请参阅更多详细信息 Move constructor on derived object