深拷贝

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
class instance
{
public:
int age;
int* height;
instance(int a,int h)
{
age = a;
cout << a << endl;
height=new int(h);
cout << *height << endl;
}
~instance()
{
if (height != NULL)
{
delete height;
height = NULL;
cout << "已清空" << endl;
}
}
instance(const instance& p)
{
age = p.age;
//height = p.height;编译器默认实现的就是这行代码
//深拷贝如下
height = new int(*p.height);
}
};


//浅拷贝使两个height指向同一内存地址,会导致将已释放的内存再次释放,引发双重释放安全问题
void test01()
{
instance p1(18,160);
instance p2(p1);
cout << p2.age <<*p2.height<<endl;
}
int main()
{
test01();
system("pause");
}

重载赋值运算符

众所周知,运算符重载后使运算符能实现原本无法完成的工作
赋值运算符,这里我们实现类对类的赋值.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62

class MyClass {
private:
char* data;

public:
// 默认构造函数
MyClass(const char* str = "") {
data = new char[strlen(str) + 1];
strcpy(data, str);
}

// 拷贝构造函数
MyClass(const MyClass& other) {
data = new char[strlen(other.data) + 1];
strcpy(data, other.data);
}

// 重载赋值运算符
MyClass& operator=(const MyClass& other) {
if (this == &other) {
return *this; // 处理自赋值情况
}

// 先释放原有资源
delete[] data;

// 分配新内存并拷贝数据
data = new char[strlen(other.data) + 1];
strcpy(data, other.data);

return *this;
}

// 析构函数
~MyClass() {
delete[] data;
}

// 打印数据
void print() const {
std::cout << data << std::endl;
}
};

int main() {
MyClass a("Hello");
MyClass b("World");

std::cout << "Before assignment:" << std::endl;
a.print(); // 输出 "Hello"
b.print(); // 输出 "World"

a = b; // 使用重载的赋值运算符

std::cout << "After assignment:" << std::endl;
a.print(); // 输出 "World"
b.print(); // 输出 "World"

return 0;
}

注意:一定要将被赋值对象中在堆中的数据释放掉.

否则会导致旧资源直接被新资源赋值后,内存覆盖掉

有内存泄露,资源浪费的风险,以及未定义行为的风险

具体会不会发生所谓的双重释放,个人认为不会