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

C++同对象拷贝赋值疑问:remove_from_Folders为何不影响rhs.folders?

《C++ Primer》Message类拷贝赋值运算符自赋值问题解析

核心结论:编译器没有特殊规则,代码能运行是因为自赋值的执行流程恰好达成了(或看起来达成了)合理状态,本质需看remove_from_Folders()的具体实现


  1. 拆解remove_from_Folders()的作用
    原书里该函数的核心逻辑是遍历当前Message的folders集合,让每个关联的Folder对象将此Message从自身的消息列表中移除。是否清空Message自己的folders容器,是关键分歧点:

    • 若仅让Folder移除Message,不清空folders
      自赋值时,rhs就是当前对象的引用:

      • 调用remove_from_Folders():Message从所有Folder中移除,但自身folders仍保留原Folder指针集合。
      • 执行folders = rhs.folders:因rhs是自己,相当于容器自我赋值,内容不变。
      • 调用add_to_Folders(rhs):遍历folders,将Message重新添加到所有Folder的消息列表。
        最终Message的状态和自赋值前完全一致,所以代码表现正常。
    • 若既让Folder移除Message,又清空folders
      自赋值时流程会导致异常:

      • remove_from_Folders()执行后,Message脱离所有Folder,且自身folders为空。
      • folders = rhs.folders:rhs.folders已为空,赋值后folders仍为空。
      • add_to_Folders(rhs)遍历空集合,无任何操作。
        此时Message已不属于任何Folder,状态被修改——若你觉得“正常运行”,大概率是测试时仅检查了Message的内容,未验证Folder的关联关系。
  2. 编译器无特殊处理
    自赋值完全遵循C++引用与运算符重载的常规规则,编译器不会对赋值运算符做额外的逻辑干预。部分场景下的“正常运行”,要么是流程抵消了影响,要么是测试覆盖不全。

  3. 标准写法需加入自赋值判断
    为避免无用操作与潜在逻辑错误,规范的拷贝赋值运算符应先判断是否为自赋值:

    Message& Message::operator=(const Message& rhs) {
        if (this != &rhs) {
            remove_from_Folders();
            contents = rhs.contents;
            folders = rhs.folders;
            add_to_Folders(rhs);
        }
        return *this;
    }
    

内容的提问来源于stack exchange,提问作者J.Doe

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 04:45:37