/********** BEGIN **********/ #include <iostream> using namespace std; #include"ArrayList.h" ArrayList::ArrayList() { data=new int(100); size=0; capacity=100; } //拷贝构造函数,构造一个逻辑上与参数内容相同的顺序表 ArrayList::ArrayList(const ArrayList&rhs) { this->size=rhs.getSize(); capacity=100; for(int i=0;i<size;i++) { data[i]=rhs.data[i]; } } //原生数组构造函数,构造一个内容与给定数组相同的顺序表 ArrayList::ArrayList(int const a[],int n) { size=n; capacity=100; for(int i=0;i<size;i++) { data[i]=a[i]; } } //填充构造函数,构造一个内容为n个value的顺序表 ArrayList::ArrayList(int n,int value) { size=n; capacity=100; for(int i=0;i<size;i++) { data[i]=value; } } //析构函数,一定要自行实现,否则有内存泄漏 ArrayList::~ArrayList() { delete data; } /********** END **********/那有问题
时间: 2025-06-25 22:08:08 浏览: 18
### C++ 中 ArrayList 类实现的代码审查
在 C++ 中,`ArrayList` 的实现通常涉及动态数组的概念。以下是关于 `ArrayList` 实现中需要注意的关键点以及如何正确编写其 **拷贝构造函数** 和 **析构函数** 的说明。
#### 1. 动态内存分配
由于 `ArrayList` 使用的是动态数组,因此需要显式地管理内存。这涉及到以下几个方面:
- 在构造函数中分配内存。
- 在析构函数中释放内存。
- 如果实现了拷贝构造函数,则需深拷贝以避免浅拷贝带来的问题[^1]。
#### 2. 拷贝构造函数
如果未正确实现拷贝构造函数,可能会导致两个对象共享相同的指针数据区域,进而引发双重删除或其他未定义行为。以下是一个典型的拷贝构造函数实现:
```cpp
class ArrayList {
private:
int* data; // 动态数组指针
size_t capacity; // 容量
size_t size; // 当前大小
public:
// 默认构造函数
ArrayList() : data(nullptr), capacity(0), size(0) {}
// 参数化构造函数
explicit ArrayList(size_t initialCapacity) : capacity(initialCapacity), size(0) {
data = new int[capacity];
}
// 拷贝构造函数 (深拷贝)
ArrayList(const ArrayList& other) : capacity(other.capacity), size(other.size) {
data = new int[capacity]; // 分配新空间
std::copy(other.data, other.data + size, data); // 深拷贝数据
}
// 析构函数
~ArrayList() {
delete[] data; // 释放动态分配的内存
}
};
```
#### 3. 析构函数
析构函数的作用是清理资源,在这里主要是释放动态分配的内存。如果没有析构函数或析构函数未能正确释放内存,将会导致内存泄漏。
#### 4. 赋值运算符重载
除了拷贝构造函数外,还需要考虑赋值操作的行为。如果不重载赋值运算符,默认行为可能导致浅拷贝问题。可以通过三步法(检查、释放、复制)来安全地实现赋值运算符:
```cpp
// 赋值运算符重载
ArrayList& operator=(const ArrayList& other) {
if (this != &other) { // 自我赋值检查
delete[] data; // 释放当前资源
capacity = other.capacity;
size = other.size;
data = new int[capacity]; // 分配新空间
std::copy(other.data, other.data + size, data); // 深拷贝数据
}
return *this;
}
```
#### 5. 扩展容量机制
为了支持动态增长,`ArrayList` 应该具备扩展容量的功能。常见的做法是当数组满时创建一个新的更大的数组,并将旧数组的数据复制过去。
```cpp
void resize() {
if (size >= capacity) {
int newCapacity = (capacity == 0) ? 1 : capacity * 2;
int* newData = new int[newCapacity];
std::copy(data, data + size, newData);
delete[] data;
data = newData;
capacity = newCapacity;
}
}
void add(int value) {
resize();
data[size++] = value;
}
```
---
### 关键注意事项
1. **内存泄漏**: 确保每次动态分配的内存都被正确释放。
2. **浅拷贝 vs 深拷贝**: 拷贝构造函数和赋值运算符应始终采用深拷贝策略。
3. **异常安全性**: 在动态分配内存时可能发生异常,建议使用智能指针(如 `std::unique_ptr` 或 `std::shared_ptr`)替代原始指针以增强安全性[^2]。
---
阅读全文
相关推荐







