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

std::move结合多态移动赋值运算符的内存安全问题

结论

你写的Child类移动赋值运算符内,先调用父类移动赋值、再移动子类成员str3_的两行逻辑完全内存安全,没有内存违规风险。

原理说明
  • 调用父类移动赋值时不会移动整个子类对象。执行Parent::operator=(std::move(other))时,std::move(other)生成的Child类型右值会隐式转换为绑定到other内部Parent基类子对象的Parent&&右值引用,这个引用从类型层面就只能访问Parent类定义的成员,根本碰不到Child独有的str3_。
  • 父类移动赋值的作用范围严格限定在基类子对象。Parent的移动赋值运算符是Parent的成员函数,内部逻辑仅移动Parent自身的str1_、str2_两个成员,它感知不到Child类的存在,也没有途径访问或修改Child的派生部分成员。这行调用执行完成后,other的str3_成员没有被任何操作改动,后续对str3_做移动赋值完全合法。
  • 代码中的自赋值检查逻辑可以正常生效。无论是Child层还是Parent层的if (this == &other)判断,在自赋值场景下都能正确识别同一对象,不会出现重复移动自身成员的问题。
误区提醒

不要把调用父类移动赋值的操作和内存级整块对象移动混淆。C继承体系下,基类成员函数默认只处理当前类对应的子对象部分,只有显式使用memcpy/memmove做整块内存覆盖、或者父类移动赋值被错误实现为越界操作时才会触发内存问题。你给出的示例里,父类移动赋值仅对自身的std::string成员调用标准库的移动赋值,完全符合C对象模型的安全要求。

class Parent
{
public:
     // Constructors

     Parent& operator=(Parent&& other) noexcept
     {
          if (this == &other)
               return *this;

          str1_ = std::move(other.str1_);
          str2_ = std::move(other.str2_);
          return *this;
     }

protected:
     std::string str1_, str2_;
};

class Child : public Parent
{
public:
     // Constructors

     Child& operator=(Child&& other) noexcept
     {
          if (this == &other)
               return *this;

          // 以下两行逻辑内存安全
          Parent::operator=(std::move(other));
          str3_ = std::move(other.str3_);

          return *this;
     }

private:
     std::string str3_;
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 20:48:19