Course类拷贝构造器问题:拷贝对象修改致原对象变更
问题描述
我正在为Course类实现拷贝构造器,当前实现导致部分单元测试失败。单元测试显示,用已有Course对象初始化新对象后,修改新对象时原对象也会被改变,二者本应相互独立。我无法修改单元测试,需修复拷贝构造器。
相关代码
Course类定义
class Course { //** You may not change the declarations in this private: area. CourseName name; ///< 课程名称 int numberOfPrerequisites; ///< 当前数组中的前置课程数量 int maxPrerequisites; ///< 数组可容纳的最大前置课程数量 CourseName * prereqs; };
当前拷贝构造器代码
Course::Course(const Course& other) : name(other.name), numberOfPrerequisites(other.numberOfPrerequisites), maxPrerequisites(other.maxPrerequisites), prereqs(new CourseName[other.maxPrerequisites]) { // 复制所有前置课程 for (int i = 0; i < numberOfPrerequisites; ++i) { prereqs[i] = other.prereqs[i]; } }
已尝试的运算符重载代码
等于运算符
bool Course::operator==(const Course& other) const { return name == other.name; }
赋值运算符
Course& Course::operator=(const Course& other) { if (this == &other) return *this; name = other.name; numberOfPrerequisites = other.numberOfPrerequisites; maxPrerequisites = other.maxPrerequisites; delete[] prereqs; prereqs = new CourseName[other.maxPrerequisites]; // 将源对象的前置课程复制到新对象 for (int i = 0; i < numberOfPrerequisites; ++i) { prereqs[i] = other.prereqs[i]; } return *this; }
修复方案
问题核心是深拷贝不彻底:你已经为prereqs数组分配了新的内存空间,但如果CourseName类本身包含动态分配的资源(比如指针)且未实现正确的深拷贝逻辑(拷贝构造器、赋值运算符),那么数组中每个CourseName对象的拷贝只是浅拷贝——新旧对象的CourseName会共享底层资源,修改新对象的元素自然会影响原对象。
方案1:修复CourseName的深拷贝(若有权限修改)
给CourseName实现正确的拷贝构造器和赋值运算符,确保其内部的动态资源被完整复制,而非仅复制指针。示例如下(假设CourseName内部有动态分配的字符串):
class CourseName { char* name; public: CourseName(const CourseName& other) { // 分配新内存并复制内容 name = new char[strlen(other.name) + 1]; strcpy(name, other.name); } CourseName& operator=(const CourseName& other) { if (this == &other) return *this; // 释放原有内存 delete[] name; // 分配新内存并复制 name = new char[strlen(other.name) + 1]; strcpy(name, other.name); return *this; } ~CourseName() { delete[] name; } };
方案2:在Course层手动完成深拷贝(无法修改CourseName时)
如果不能修改CourseName,则在Course的拷贝逻辑中,通过CourseName的拷贝构造函数创建全新的对象,替换简单的赋值操作:
修改拷贝构造器:
Course::Course(const Course& other) : name(other.name), numberOfPrerequisites(other.numberOfPrerequisites), maxPrerequisites(other.maxPrerequisites), prereqs(new CourseName[other.maxPrerequisites]) { for (int i = 0; i < numberOfPrerequisites; ++i) { // 用拷贝构造创建新的CourseName对象,而非浅赋值 prereqs[i] = CourseName(other.prereqs[i]); } }
同步修改赋值运算符:
Course& Course::operator=(const Course& other) { if (this == &other) return *this; name = other.name; numberOfPrerequisites = other.numberOfPrerequisites; maxPrerequisites = other.maxPrerequisites; delete[] prereqs; prereqs = new CourseName[other.maxPrerequisites]; for (int i = 0; i < numberOfPrerequisites; ++i) { prereqs[i] = CourseName(other.prereqs[i]); } return *this; }
额外注意:添加析构函数
确保Course类有正确的析构函数释放prereqs数组,避免内存泄漏:
Course::~Course() { delete[] prereqs; }
内容的提问来源于stack exchange,提问作者TobyFromHR
相关产品推荐
相关产品推荐

