关键因素
- 自我赋值检查:在赋值运算符重载函数内部,首先要检查是否是自我赋值。如果是自我赋值,直接返回
*this
,避免不必要的内存释放和重新分配。
- 释放旧资源:在为对象分配新的内存之前,需要释放对象当前已有的动态分配的内存,以防止内存泄漏。
- 深拷贝:由于指针成员变量指向动态分配的内存,在赋值时需要进行深拷贝,即分配新的内存并将源对象指针指向的内容复制到新分配的内存中。
- 处理继承体系:如果涉及继承体系,需要先调用基类的赋值运算符重载函数,以正确处理基类部分的成员变量。
实现代码
#include <iostream>
#include <cstring>
// 基类
class Base {
public:
Base() : data(nullptr), length(0) {}
Base(const char* str) {
if (str) {
length = std::strlen(str);
data = new char[length + 1];
std::strcpy(data, str);
} else {
length = 0;
data = nullptr;
}
}
Base(const Base& other) {
length = other.length;
if (other.data) {
data = new char[length + 1];
std::strcpy(data, other.data);
} else {
data = nullptr;
}
}
Base& operator=(const Base& other) {
if (this == &other) {
return *this;
}
delete[] data;
length = other.length;
if (other.data) {
data = new char[length + 1];
std::strcpy(data, other.data);
} else {
data = nullptr;
}
return *this;
}
~Base() {
delete[] data;
}
private:
char* data;
size_t length;
};
// 派生类
class Derived : public Base {
public:
Derived() : extraData(nullptr) {}
Derived(const char* str, const char* extra) : Base(str) {
if (extra) {
extraLength = std::strlen(extra);
extraData = new char[extraLength + 1];
std::strcpy(extraData, extra);
} else {
extraLength = 0;
extraData = nullptr;
}
}
Derived(const Derived& other) : Base(other) {
extraLength = other.extraLength;
if (other.extraData) {
extraData = new char[extraLength + 1];
std::strcpy(extraData, other.extraData);
} else {
extraData = nullptr;
}
}
Derived& operator=(const Derived& other) {
if (this == &other) {
return *this;
}
Base::operator=(other); // 调用基类赋值运算符
delete[] extraData;
extraLength = other.extraLength;
if (other.extraData) {
extraData = new char[extraLength + 1];
std::strcpy(extraData, other.extraData);
} else {
extraData = nullptr;
}
return *this;
}
~Derived() {
delete[] extraData;
}
private:
char* extraData;
size_t extraLength;
};