复制动态阵列并使用过载的操作员删除原件
Copying a dynamic array and deleting the original using an overloaded operator
我正在创建一个可以跟踪学生的课程。在此课程中,我使用一个Overloaded =复制这些学生对象。要跟踪他们的课程,我使用一个动态数组。阵列的副本很好。但是,在清除学生对象的变量时,从之前复制的任何对象也都会擦拭数组。这是代码:
#include <iostream>
#include <string>
using namespace std;
class Student
{
string name; //Name
string* classList = NULL; //Empty array to store class names in
int numClasses = 0; //Number of classes
public:
void InputData()
{
cout << "Enter student name: " << endl; //Input Name
cin >> name;
cout << "Enter number of classes: " << endl; //Input classes
cin >> numClasses;
classList = new string[numClasses]; //Define array size
for (int i = 0; i < numClasses; i++) //For every spot in array, name class
{
cout << "Enter name of class " << (i + 1) << ":" << endl; //Name class
cin >> classList[i];
}
};
void OutputData()
{
cout << "Name: " << name << endl; //Output data
cout << "Number of Classes: " << numClasses << endl;
for (int i = 0; i < numClasses; i++) //Cycle through and output classes
{
cout << "Class " << i << ": " << classList[i] << endl;
}
};
void ResetClasses()
{
name = "";
delete[] classList; //Free Memory
classList = NULL; //Clear array
numClasses = 0;
};
Student operator =(Student& student) //Overload =
{
this->name = student.name;
this->classList = student.classList;
this->numClasses = student.numClasses;
return *this;
};
};
int main()
{
Student s1, s2;
s1.InputData(); // Input data for student 1
cout << "Student 1's data:" << endl;
s1.OutputData(); // Output data for student 1
s2 = s1;
cout << "Student 2's data after assignment from student 1:" << endl;
s2.OutputData(); // Should output same data as for student 1
s1.ResetClasses();
cout << "Student 1's data after reset:" << endl;
s1.OutputData(); // Should have no classes
cout << "Student 2's data, should still have original classes:" << endl;
s2.OutputData(); // Should still have original classes
}
主要罪犯几乎可以肯定是这两个
中的任何一个 void ResetClasses()
{
name = "";
delete[] classList; //Free Memory
classList = NULL; //Clear array
numClasses = 0;
};
Student operator =(Student& student) //Overload =
{
this->name = student.name;
this->classList = student.classList;
this->numClasses = student.numClasses;
return *this;
};
程序的输出是:
Enter student name:
ERIC
Enter number of classes:
2
Enter name of class 1:
C++
Enter name of class 2:
C
Student 1's data:
Name: ERIC
Number of Classes: 2
Class 0: C++
Class 1: C
Student 2's data after assignment from student 1:
Name: ERIC
Number of Classes: 2
Class 0: C++
Class 1: C
Student 1's data after reset:
Name:
Number of Classes: 0
Student 2's data, should still have original classes:
Name: ERIC
Number of Classes: 2
Class 0:
Class 1:
造成这一点我会做什么?
Student operator =(Student& student)
分配操作员应采用const
参考参数。分配运算符还应返回参考,而不是值。
此类也缺少复制构造函数。
在分配运营商中:
this->classList = student.classList;
这是一个简单的指针。对于初学者来说,这是一个内存泄漏。以前的指针(如果有的话)丢失,并且其分配的内存被泄漏。
现在,您有两个使用相同的classList
指针的实例。因此,当resetClasses()
方法在其中一个类中调用时,它将被删除,并且由于类的另一个实例具有相同的指针,因此现在指向删除内存。
如果有的话,您的分配运算符必须正确删除现有数组,并克隆在实例中持有的数组(如果有)。其中大部分也适用于您必须实现的复制构造函数。
此类也缺少一个破坏者,这将导致另一个内存泄漏。
您遇到了班级的所有这些基本问题。您必须修复所有这些,以使您的班级正常工作。您必须实施适当的复制构造函数,分配运算符和驱动器,该构造器正确克隆,复制和破坏您的班级持有的数据实例。
看来,您尚未学会如何使用容器和智能指针,以及您是否要学习如何正确跟踪分配的内存,避免内存损坏和内存泄漏的方法。这显然是一项重要的学习技能。但是,一旦您弄清楚了所有这些,并且您的班级正常工作,您就可以将指针替换为std::vector
,而不再担心它。
您需要创建类列表的副本,否则两个学生对象都会在内存中指向相同位置。
释放这些领域之一将导致另一个领域也被释放。
在您的复制构造函数和分配运算符中,创建一个新对象的新数组,然后将每个元素复制到新对象。
- 将数组的地址分配给变量并删除
- 删除一个线程上有数百万个字符串的大型哈希映射会影响另一个线程的性能
- C/C++编译器通常会删除重复的库吗
- 从链接列表c++中删除一个项目
- C++如何通过用户输入删除列表元素
- 为什么在C++中使用私有复制构造函数与删除复制构造函数
- 使用自定义参数的过载删除操作员
- 使用C 中的操作员删除的分割故障
- 在抽象类中删除操作员,它如何工作
- 继承类上的运算符new和delete.操作员删除未执行
- 为什么被删除=操作员,我该如何工作
- c 从范围删除对象的操作员导致崩溃dealloceLoceLoceLoceLoceLoceLoceLoceLoceL
- MINGW中的全局超载操作员新/删除
- 复制动态阵列并使用过载的操作员删除原件
- C 删除具有内存位置的操作员
- 删除的操作员隐藏了类操作员
- 基本的新建/删除操作员日志记录
- Clang链接时间优化与替换的操作员新的原因不匹配的自由()/删除在valgrind
- 删除操作员内存管理
- 自动删除新操作员