You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何以下示例中自定义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

原因解释

  1. std::move的本质是类型转换,而非对象转移:std::move只是把左值强制转换成右值引用类型,它本身不会触发任何构造函数——构造函数只有在创建新对象的时候才会被调用。
  2. 你的代码没有创建新对象:在main函数里,你用std::move(demo)传给fun,而fun的参数是Demo&& tempObj,这只是一个右值引用绑定,tempObj只是原对象demo的一个别名,操作它就是直接操作原对象,完全没有新的Demo对象被创建,自然不会调用移动构造函数。
  3. 触发移动构造的条件:只有当你用右值引用去初始化一个新的对象时,才会调用移动构造函数。比如修改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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 09:53:01