设计思路
- 考虑成员变量:对于包含动态资源分配的成员变量(如动态数组、智能指针),在赋值运算符重载函数中需要正确处理资源的释放与重新分配。
- 异常安全性:采用“拷贝并交换”(copy-and-swap)技术来实现异常安全。这种技术先创建一个临时对象,将其成员变量与目标对象的成员变量交换,这样如果在创建临时对象或交换过程中抛出异常,原对象的状态不会改变,不会发生内存泄漏。
- 自赋值检查:在赋值运算符重载函数开始时,先检查是否为自赋值,避免不必要的操作。
代码实现
#include <iostream>
#include <memory>
class ComplexData {
private:
int* dynamicArray;
std::unique_ptr<int> smartPtr;
int regularVariable;
public:
ComplexData() : dynamicArray(nullptr), smartPtr(nullptr), regularVariable(0) {}
ComplexData(int size, int value, int regValue)
: regularVariable(regValue) {
dynamicArray = new int[size];
for (int i = 0; i < size; ++i) {
dynamicArray[i] = value;
}
smartPtr = std::make_unique<int>(value);
}
~ComplexData() {
delete[] dynamicArray;
}
// 拷贝构造函数
ComplexData(const ComplexData& other)
: regularVariable(other.regularVariable) {
if (other.dynamicArray) {
int size = 0;
while (other.dynamicArray[size] != 0) {
++size;
}
dynamicArray = new int[size];
for (int i = 0; i < size; ++i) {
dynamicArray[i] = other.dynamicArray[i];
}
} else {
dynamicArray = nullptr;
}
smartPtr = std::make_unique<int>(*other.smartPtr);
}
// 赋值运算符重载
ComplexData& operator=(ComplexData other) {
// 自赋值检查
if (this == &other) {
return *this;
}
// 交换成员变量
std::swap(dynamicArray, other.dynamicArray);
std::swap(smartPtr, other.smartPtr);
std::swap(regularVariable, other.regularVariable);
return *this;
}
void print() const {
if (dynamicArray) {
std::cout << "Dynamic Array: ";
for (int i = 0; dynamicArray[i] != 0; ++i) {
std::cout << dynamicArray[i] << " ";
}
std::cout << std::endl;
}
std::cout << "Smart Ptr: " << *smartPtr << std::endl;
std::cout << "Regular Variable: " << regularVariable << std::endl;
}
};
int main() {
ComplexData obj1(3, 10, 20);
ComplexData obj2;
obj2 = obj1;
obj1.print();
obj2.print();
return 0;
}