编译错误:表达式不可修改——狗狗仓库年龄更新代码问题
解决“Expression is not modifiable”编译错误:修改狗狗仓库年龄的问题
我一眼就看出你代码里的两个关键问题,先帮你拆解清楚:
1. 直接报错的根源:getAge()返回的是不可修改的值
你写的d2.getAge() = ageToUpdate之所以报错,是因为你的Dog::getAge()成员函数大概率是这样的:
int getAge() const { // 返回值拷贝,且是const成员函数 return age; }
这种写法返回的是age的一个临时拷贝,不是指向原成员变量的引用——临时值是右值,不能被赋值,所以编译器会提示“表达式不可修改”。
2. 隐藏的逻辑bug:你修改的是拷贝而非原对象
就算你解决了赋值的问题,当前代码还有个隐形坑:Dog d2 = dogsInDynamicVector[i];是把数组里的狗狗对象拷贝到了局部变量d2里,你修改d2的年龄根本不会影响仓库里的原对象!等于白忙活一场。
两种可行的修复方案
方案一:给Dog类添加setAge()成员函数(更符合封装原则)
这种方式不用暴露成员变量的可修改引用,是面向对象编程的常规做法:
// 在Dog类的头文件中添加声明 class Dog { private: int age; // 其他成员... public: void setAge(int newAge) { age = newAge; } // 其他成员函数... };
然后修改你的仓库代码,同时把局部变量改成引用,直接操作原对象:
bool Repository::updateDogAge(const Dog& d, const int& ageToUpdate) { Dog* dogsInDynamicVector = this->dogs.getAllElems(); if (dogsInDynamicVector == NULL) return false; for (int i = 0; i < this->dogs.getSize(); i++) { Dog& d2 = dogsInDynamicVector[i]; // 用引用绑定原对象,避免拷贝 if (d2.getName() == d.getName()) { d2.setAge(ageToUpdate); // 调用setAge修改年龄 break; // 找到目标后提前退出循环,提升效率 } } return true; }
方案二:修改getAge()让它返回可修改引用(适合需要直接操作成员的场景)
如果你确实需要通过getAge()直接修改年龄,可以把它改成返回引用:
// Dog类中的声明 int& getAge(); // 实现文件中的定义 int& Dog::getAge() { return age; }
然后仓库代码里的赋值语句就可以直接生效了(同样要把d2改成引用):
if (d2.getName() == d.getName()) { d2.getAge() = ageToUpdate; // 现在返回的是原成员的引用,可以赋值 break; }
额外提醒
- 确保
getAllElems()返回的指针指向的是仓库容器中实际存储的狗狗对象,而不是临时拷贝的数组 - 如果你的
DynamicVector容器是const的,那还需要调整容器的访问权限,确保可以修改内部元素
内容的提问来源于stack exchange,提问作者Bryuki HK
相关产品推荐
相关产品推荐

