c++ - 如果我还使用复制构造函数和重载 = 运算符,是否需要析构函数?
问题描述
所以我有这个代码,我有一个类 Student,它是一个带有 *ModuleGrade 类对象的向量。我在 Student 类中有一个析构函数,但在 = 运算符的重载中我也有一个析构函数。我是否需要两次都拥有它,或者我可以将析构函数保留在 Student 类中,它也会在 = 运算符的重载中完成这项工作。我希望我能解释清楚。
编辑: 我知道如果向量没有 * 会更好,但这样做的目的是让我展示我理解 * 和深拷贝构造函数的工作原理。
这是我的代码:
学生.h
private:
int studentNumber;
vector <ModuleGrade*> gradeList;
public:
~Student();
Student(const Student& student); // user-defined copy ctor
Student& operator = (const Student& student);
学生.cpp
Student::~Student()
{
int number = gradeList.size();
for(int i= 0; i<number; i++){
delete gradeList[i];
}
}
Student::Student(const Student &student ) : Person(student) {
//deep copy constructor
this->studentNumber=student.studentNumber;
int size = student.gradeList.size();
for(int i=0; i <size; i++) {
// ModuleGrade *m ;
ModuleGrade *mg = new ModuleGrade(*(student.gradeList[i]));
gradeList.push_back(mg);
}
}
Student& Student :: operator = (const Student & student) {
if (&student == this) return *this;
Person :: operator=(student);
studentNumber = student.studentNumber;
//delete gradeList of this
//SHOULD I DO THIS IF THERE IS A DESTRUCTOR DECLARED???
for (unsigned int i=0; i<gradeList.size(); i++){
delete gradeList[i];
gradeList.clear();
}
//fill this with grades of student
for(unsigned int i=0; i<student.gradeList.size(); i++) {
ModuleGrade *m = new ModuleGrade(*(student.gradeList[i]));
gradeList.push_back(m);
}
return *this;
}
解决方案
是的,如果您管理指针,那么您需要确保在分配和销毁时清理指向的对象。
这就是人们经常使用 move 和 swap 来编写赋值运算符的原因:
X& operator=(X const& other){
X temp(other);
swap(temp);
return *this;
}
因为清理然后只需要写在析构函数中。swap
只是交换内容,复制构造函数分配新的内容。
使用 move-and-swap 还涵盖了您编写的情况,x=x
否则,如果您在尝试从另一个对象复制数据之前破坏了被分配对象指向的数据,则需要在赋值运算符中显式测试该情况目的。
此外,在实际代码中,您应该使用std::unique_ptr
或者std::shared_ptr
如果您想通过指针保存对象:您永远不必delete
手动编写,您也可以经常使用std::make_unique
orstd::make_shared
来代替new
。
推荐阅读
- swift - 如果在剪辑结束之前开始播放,AudioKit AKClipPlayer 会崩溃
- regex - 替换 Json 文件中的分隔符字符串
- opengl - PBR 纹理和 Phong Shading 模型材质参数
- html - 我从服务器下载了一个项目,但图像没有以正确的路径显示
- elasticsearch - ElasticSearch:错误的相关顺序
- c# - 为什么成员变量不遵循递归返回规则?
- javascript - 当您不知道触发了哪些事件时,如何在更改输入字段的值后触发单击/更改事件
- wso2 - 带传感器的逻辑模式
- python - 3D 卷积自动编码器与输入层不匹配输出层
- c# - 使用 FileHelpers nuget 包读取条形码