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

如何修改C++代码以访问对象的原始成员而非副本,实现礼物列表的更新?

问题分析与修复方案

嘿,我一眼就看出问题所在了——你现在操作的都是对象的副本,不是原始数据!这就是为什么修改后原始列表毫无变化的原因。下面给你详细拆解问题和解决步骤:

核心问题根源

你代码里的两个关键方法都是返回值拷贝,而不是直接引用原始对象:

  • Child::getList()返回的是ArrayList<string>的副本,不是内部那个presents列表本身;
  • ArrayList::getEntry()返回的也是Child对象的副本,不是列表里存储的原始Child实例。
    所以当你执行this->getEntry(position).getList().insert(...)时,你只是在临时创建的Child副本里修改了它的礼物列表副本,这些临时对象执行完就被销毁了,原始数据当然纹丝不动。

一步步修复代码

我们需要修改两个类的方法,让它们返回引用,这样就能直接操作原始对象:

1. 改造Child类的礼物列表访问方法

给Child添加一个返回可修改引用的getList(),同时保留只读版本(遵循const正确性):

// Child.h 中的类声明修改
class Child {
private:
    string name;
    ArrayList<string> presents;
public:
    string getName() const;
    // 新增:返回可修改的引用,用于修改礼物列表
    ArrayList<string>& getList();
    // 保留:返回只读引用,用于只需要查看的场景
    const ArrayList<string>& getList() const;
    void setName(string name);
    void setList(ArrayList<string> aList);
};

// 实现这两个方法
ArrayList<string>& Child::getList() {
    return presents;
}

const ArrayList<string>& Child::getList() const {
    return presents;
}

2. 改造ArrayList的getEntry方法

同样,新增返回非const引用的版本,让我们能修改列表里的原始对象:

// ArrayList.h 中的类声明修改
template<class ItemType>
class ArrayList {
    // ... 原有私有/保护成员不变 ...
public:
    // ... 原有方法不变 ...
    // 新增:返回可修改的对象引用
    ItemType& getEntry(int position) throw(PrecondViolatedExcep);
    // 修改原有const版本的返回类型为const引用
    const ItemType& getEntry(int position) const throw(PrecondViolatedExcep);
};

// 实现非const版本的getEntry
template<class ItemType>
ItemType& ArrayList<ItemType>::getEntry(int position) throw(PrecondViolatedExcep) {
    bool ableToGet = (position >= 1) && (position <= itemCount);
    if (ableToGet)
        return items[position - 1];
    else {
        string message = "getEntry() called with an empty list or invalid position.";
        throw(PrecondViolatedExcep(message));
    }
}

// 修改原有const版本的getEntry返回类型
template<class ItemType>
const ItemType& ArrayList<ItemType>::getEntry(int position) const throw(PrecondViolatedExcep) {
    bool ableToGet = (position >= 1) && (position <= itemCount);
    if (ableToGet)
        return items[position - 1];
    else {
        string message = "getEntry() called with an empty list or invalid position.";
        throw(PrecondViolatedExcep(message));
    }
}

3. 修正insertPresent方法

现在我们可以直接操作原始Child对象的礼物列表了,顺便优化一下逻辑(比如把礼物插在列表末尾,增加未找到孩子的判断):

template<class ItemType>
bool NiceArrayList<ItemType>::insertPresent(string name, string newEntry) {
    bool ableToInsert = false;
    int length = this->getLength();
    int targetPosition = -1;

    // 先遍历找到对应名字的Child位置
    for (int i = 1; i <= length; i++) {
        if (this->getEntry(i).getName() == name) {
            targetPosition = i;
            break;
        }
    }

    // 没找到对应名字的孩子,直接返回失败
    if (targetPosition == -1) {
        return false;
    }

    // 直接操作原始Child对象的礼物列表,插入到末尾
    auto& targetChild = this->getEntry(targetPosition);
    ableToInsert = targetChild.getList().insert(targetChild.getList().getLength() + 1, newEntry);
    return ableToInsert;
}

补充小提示

  • 使用引用不仅能解决你的问题,还能避免不必要的对象拷贝,提升代码性能;
  • 区分const和非const版本的方法是C++里的最佳实践,保证了const正确性——当你拿到一个const Child对象时,只能调用const方法,不会不小心修改它。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.28 17:37:33