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

技术问询:移动构造函数是否仅影响类指针成员指向的内存空间?

关于C++移动构造函数的疑问解答

首先直接回应你的两个核心问题:

  1. 移动构造函数不是仅影响类的指针成员指向的内存空间,它会处理类的所有成员,只是不同类型的成员处理逻辑不一样。
  2. 你对拷贝/移动构造的理解存在偏差,不是两种构造都会把成员值存到新内存并释放旧内存,两者的核心逻辑差异很大。

先拆解两种构造函数的本质

结合你给出的President类代码来分析:

  • 拷贝构造函数:
    你的代码里拷贝构造对name、country做普通拷贝,year直接复制。对于std::string这种自带堆内存管理的类型,普通拷贝是深拷贝——新对象的string会重新分配一块堆内存,把原对象string里的字符全部复制过去;int这种基本类型就是直接复制数值。
    这个过程中,原对象的所有成员完全不受影响,它的内存不会被释放,原对象依然是一个完整有效的实例。

  • 移动构造函数:
    移动构造的核心是资源转移,而不是复制:

    • 对于std::string这类带堆资源的成员:它会直接把原对象string内部指向堆内存的指针"移交"给新对象,同时把原对象的string置为一个"有效但空"的状态(比如长度为0)。这个过程不会分配新的堆内存,只是转移了已有内存的所有权。
    • 对于int year这种基本类型:因为没有堆内存资源可以转移,所以就是直接复制数值——毕竟基本类型的大小很小,复制的成本可以忽略。
      移动构造完成后,原对象的带资源成员已经是空状态,当原对象销毁时,只会释放这个空状态的资源(相当于啥也没做),而原来的堆内存已经属于新对象,由新对象负责最终销毁。

纠正你的理解误区

你说"两种构造都会将三个数据成员的值存储到新的内存空间中,同时释放旧内存",这是不对的:

  • 拷贝构造会为带资源成员分配新内存并复制数据,但不会释放原对象的旧内存,原对象仍然可用。
  • 移动构造不会为带资源成员分配新内存(直接复用原对象的内存),也不会释放旧内存——旧内存的所有权转移给了新对象,原对象的带资源成员已经被掏空,销毁时不会碰原来的那块内存。

举个实际运行的场景

假设你写了这样的代码:

President p1("Lincoln", "USA", 1861);
President p2 = std::move(p1); // 触发移动构造

运行后你会看到:

  1. 构造p1时输出--constructed。
  2. 移动构造p2时输出--moved。
  3. 此时p1的name和country已经是空字符串了,p2拥有原来的字符串资源。
  4. 销毁时,p1先销毁,输出的name地址对应的是空字符串;p2销毁时才会释放原来的字符数组内存。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.28 12:17:42