C++通过类指针调用addPoints修改成员变量不生效问题
问题根因
调用修改方法不生效的核心原因是跨类返回关联对象的getter全部返回了对象值拷贝,而非原对象的引用,所有修改操作都落在临时生成的副本对象上,副本在语句执行结束后就会销毁,原存储的实例不会被改动。
这也刚好解释了你遇到的「getter读值正常、setter修改无效」的现象:getter只需要读取数值,副本的值和原对象完全一致,读操作看不出异常;但写操作只修改副本,完全不影响原对象。
具体问题点:
Driver类的getTeam()方法声明返回值为Team值类型,实现中return *DriversTeam;会复制指针指向的原Team对象,返回的是临时副本。Team类的getDriver(int nr)方法声明返回值为Driver值类型,实现中return *Drivers[nr];会复制指针指向的原Driver对象,返回的是临时副本。
修复方案
将两个getter的返回值改为引用类型,确保调用时拿到的是原对象而非副本:
- 修改
Driver.h中的方法声明
// 把原声明 Team getTeam(); 替换为 Team& getTeam();
对应修改Driver.cpp中的实现:
Team& Driver::getTeam() { return *DriversTeam; }
- 修改
Team.h中的方法声明
// 把原声明 Driver getDriver(int nr); 替换为 Driver& getDriver(int nr);
对应修改Team.cpp中的实现:
Driver& Team::getDriver(int nr) { return *Drivers[nr]; }
如果需要在const对象上调用这两个getter做只读操作,可以补充const重载版本,返回const引用保证安全性:
// 头文件补充声明 const Team& getTeam() const; const Driver& getDriver(int nr) const; // cpp补充实现 const Team& Driver::getTeam() const { return *DriversTeam; } const Driver& Team::getDriver(int nr) const { return *Drivers[nr]; }
修改完成后,所有通过getter发起的修改操作会直接作用在原对象上,不会再出现修改不生效的问题。
可优化的代码规范问题
- 不要在头文件中写
using namespace std;,该写法会污染所有引入该头文件的代码的命名空间,极易引发命名冲突,标准库类型建议直接用std::前缀指定,using namespace std;仅可在.cpp实现文件中按需使用。 - 布尔变量赋值直接使用布尔字面量,比如
bool found = false;,不要用整数0/1给bool类型赋值,语义更清晰。 - 类成员变量建议增加统一的命名标识(比如
m_前缀、_后缀),例如int m_points;、std::vector<Driver*> m_drivers;,和局部变量、形参做明确区分,降低读代码和维护的成本。 - 当前两个类互相持有裸指针,需要严格关注对象生命周期,避免出现指针指向的对象已被销毁、仍访问野指针的问题;如果后续业务逻辑变复杂,建议使用智能指针(互相引用场景用
std::shared_ptr搭配std::weak_ptr避免循环引用)管理对象,减少内存泄漏、野指针风险。 - 字符串比较直接使用
==运算符即可,比如iter.getName() == values[4],不需要调用compare() == 0,代码可读性更高。 - 向
std::vector中存储元素指针时要注意,vector扩容时会重新分配内存、迁移元素位置,之前存储的元素指针会失效,如果你后续需要对teams、drivers两个vector做新增元素操作,建议提前调用reserve()预留足够空间,或者直接存储智能指针避免指针失效。
内容的提问来源于stack exchange,提问作者WorthyFrog
相关产品推荐
相关产品推荐

