#include <iostream>
#include <cstring>
class MyClass {
private:
int* data;
int size;
public:
// 构造函数
MyClass(int s) : size(s) {
data = new int[size];
for (int i = 0; i < size; ++i) {
data[i] = 0;
}
}
// 拷贝构造函数
MyClass(const MyClass& other) : size(other.size) {
data = new int[size];
std::memcpy(data, other.data, size * sizeof(int));
}
// 赋值运算符重载
MyClass& operator=(const MyClass& other) {
if (this != &other) {
delete[] data;
size = other.size;
data = new int[size];
std::memcpy(data, other.data, size * sizeof(int));
}
return *this;
}
// 析构函数
~MyClass() {
delete[] data;
}
};
性能表现不同的场景:
- 拷贝构造函数:
- 场景:当通过值传递对象或者初始化一个新对象时会调用拷贝构造函数。例如:
MyClass obj1(5);
MyClass obj2 = obj1; // 调用拷贝构造函数
void func(MyClass obj);
func(obj1); // 在函数调用时,形参通过值传递,调用拷贝构造函数
- 性能特点:因为是创建新对象,通常会涉及全新的内存分配和数据复制,开销较大。如果对象较大,这种开销会更明显。
- 赋值运算符重载:
- 场景:当已经存在的对象被赋值为另一个对象时调用赋值运算符重载。例如:
MyClass obj1(5);
MyClass obj2(3);
obj2 = obj1; // 调用赋值运算符重载
- 性能特点:在赋值运算符重载中,首先要检查是否是自赋值(
this != &other
),如果不是自赋值,要释放原有内存,然后重新分配内存并复制数据。相比于拷贝构造函数,它不需要创建全新对象,在已经有对象且只是需要更新其内容的场景下,可能会比拷贝构造函数高效,尤其是在对象已经较大且需要频繁赋值的情况下。如果对象没有动态分配的资源,简单的成员变量赋值开销较小。但如果有动态资源,释放和重新分配内存的操作也会带来一定开销。