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;
str
由 std::move
、std::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
我无法理解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;
str
由 std::move
、std::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