为何以下示例中自定义move constructor未被调用?
为什么使用std::move后没有调用自定义的移动构造函数?
我原本以为用std::move(any_object)把对象转换成右值引用后,会调用我自定义的移动构造函数,但实际并没有发生这种情况,想知道原因。
代码示例
#include <iostream> #include <memory> struct Demo { int Value; Demo():Value(10) { std::cout << "Demo's default constructor called\n";} Demo(Demo& tempObj) { std::cout << "Demo non-const copy constructor called\n";} Demo(const Demo& tempObj) { std::cout << "Demo const copy constructor called\n"; } Demo(Demo&& tempObj) { std::cout << "Demo move constructor called\n"; } Demo(const Demo&& tempObj) { std::cout << "Demo const move constructor called\n"; } Demo& operator= (const Demo& tempObj){ std::cout << "Demo copy assignment operator called ";} Demo& operator= (Demo&& tempObj){ std::cout << "Demo move assignment operator called";} ~Demo(){ std::cout << "Demo's destructor called\n";} }; void fun(Demo&& tempObj) { tempObj.Value = 20; } int main() { Demo demo; fun(std::move(demo)); }
输出结果
Demo's default constructor called Demo's destructor called
原因解释
std::move的本质是类型转换,而非对象转移:std::move只是把左值强制转换成右值引用类型,它本身不会触发任何构造函数——构造函数只有在创建新对象的时候才会被调用。- 你的代码没有创建新对象:在
main函数里,你用std::move(demo)传给fun,而fun的参数是Demo&& tempObj,这只是一个右值引用绑定,tempObj只是原对象demo的一个别名,操作它就是直接操作原对象,完全没有新的Demo对象被创建,自然不会调用移动构造函数。 - 触发移动构造的条件:只有当你用右值引用去初始化一个新的对象时,才会调用移动构造函数。比如修改
fun函数:
或者在void fun(Demo&& tempObj) { // 用右值引用初始化新对象,此时会调用移动构造 Demo new_obj(std::move(tempObj)); tempObj.Value = 20; }main里直接创建新对象:int main() { Demo demo; Demo demo2(std::move(demo)); // 此处调用移动构造函数 }
移动构造函数的核心作用是用一个已存在的右值对象,快速初始化另一个新对象,重点是“创建新对象”这个动作,没有这个动作,即使有右值引用也不会触发移动构造。
内容的提问来源于stack exchange,提问作者Mangy
相关产品推荐
相关产品推荐

