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

为何我的Move构造函数未真正完成对象移动?

问题分析与解决

你代码里的移动操作没生效,核心问题出在Foo的构造函数初始化逻辑里:

  • 虽然你用std::move(vals)把vals转成右值传给了Foo的构造函数,但构造函数里的参数x是右值引用变量,只要有名字的变量都是左值,所以初始化x_(x)时调用的是vector的拷贝构造函数,而非移动构造函数。

修正方法

把Foo构造函数的初始化列表改成x_(std::move(x)),显式把左值化的右值引用参数转回右值,触发移动构造:

#include <vector>
#include <iostream>

class Foo {
 public:
  explicit Foo(std::vector<int>&& x)
      : x_(std::move(x)) {}  // 这里添加std::move触发移动构造

  void myaddr() {
    std::cout << "addr (foo ) = " << &x_ << std::endl;
    std::cout << "foo.x_ 内部数据地址 = " << x_.data() << std::endl;
  }

 private:
  std::vector<int> x_;
};

int main() {
    std::vector<int> vals = {1, 2};
    std::cout << "addr (main) = " << &vals << std::endl;
    std::cout << "vals 内部数据地址 = " << vals.data() << std::endl;

    Foo foo(std::move(vals));
    foo.myaddr();
    // 移动后vals处于有效但未定义状态,打印其内部地址大概率为空或旧值
    std::cout << "移动后vals内部数据地址 = " << vals.data() << std::endl;
}

关键说明

你之前误以为移动后&vals和&foo.x_地址会相同,这是误解:

  • vals是main栈帧里的局部变量,foo.x_是Foo对象的成员变量,它们的栈存储位置本来就不同,移动操作不会改变对象本身的存储地址。
  • 移动的本质是转移vector内部管理的堆内存资源,也就是data()返回的地址。修正后你会看到:移动前vals.data()和foo.x_.data是同一个,移动后foo的内部数据地址不变,而vals的内部数据地址会变为空(或其他无效值),这才是移动生效的标志。

内容的提问来源于stack exchange,提问作者fatdragon

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 05:12:48