深浅拷贝

深浅拷贝

浅拷贝:使用类的默认拷贝构造函数,按字节复制,对于指针型变量只复制指针本身。不会复制指针所指向的目标,两个成员指向相同的内存空间,可能造成多次释放。
没有指针时,浅拷贝是可行的。

深拷贝,自定义拷贝构造函数。

简单的测试,浅拷贝

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
class A2
{
public:
A2() :a(0),pa(nullptr) {};
~A2() {
cout << "~A2()" << endl;
delete[] pa;
}
void SetValue(int b)
{
if (pa != nullptr)
{
delete[] pa;
}
pa = new int;
*pa = b;
a = b;
}
void GetValue()
{
cout << "a: " << a << endl;
cout << "&a: " << &a << endl;
cout << "*pa: " << pa << endl;
cout << "pa: " << *pa << endl;
cout << endl;
}

private:
int a;
int* pa;
};
int main()
{
A2 a21;
{
A2 a2;
a2.SetValue(10);
a2.GetValue();
a21 = a2;
a21.GetValue();
}//a2被析构
a21.GetValue();
return 0;
}

结果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
a:   10
&a: 012FF80C
*pa: 01600550
pa: 10

a: 10
&a: 012FF81C//对象的地址不同
*pa: 01600550//指针的值相同
pa: 10

~A2()
a: 10
&a: 012FF81C//
*pa: 01600550
pa: -572662307//浅拷贝,内存已释放

深拷贝

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
class A1
{
public:
A1() :a(0), pa(nullptr) {};
~A1() {
cout << "~A2()" << endl;
delete[] pa;
}
void SetValue(int b)
{
if (pa != nullptr)
{
delete[] pa;
}
pa = new int;
*pa = b;
a = b;
}
void GetValue()
{
cout << "a: " << a << endl;
cout << "&a: " << &a << endl;
cout << "*pa: " << pa << endl;
cout << "pa: " << *pa << endl;
cout << endl;
}
A1& operator=(const A1& a1)
{
if (&a1 != this)
{
this->a = a1.a;
int* tmp = new int;
if (pa != nullptr) delete[] pa;
*tmp = *a1.pa;
pa = tmp;

}
return *this;
}

private:
int a;
int* pa;
};

int main()
{
A1 a11;
{
A1 a1;
a1.SetValue(10);
a1.GetValue();
a11 = a1;
a11.GetValue();
}
a11.GetValue();
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
a:   10
&a: 0133F7F0
*pa: 017A0550
pa: 10

a: 10
&a: 0133F800//对象的地址不同
*pa: 017A8D98//指针的值不同
pa: 10

~A2()
a: 10
&a: 0133F800
*pa: 017A8D98//析构后不受影响
pa: 10
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
class Person{
public:
    Person(){}
    explicit Person(const char* str_, int len) : strLen(len){
        str = (char*)malloc(sizeof(char)*len);
        strcpy(str, str_);
    }
    ~Person(){
        if (str != nullptr){
            free(str);
            str = nullptr;
        }
    }
    //深拷贝
    Person& operator=(const Person& person){
if (this == &person) return *this;//(错误(*this == person) )
        free(str);
        strLen = person.strLen;
        str = (char *)malloc(sizeof(char) * (strLen+1));
        memset(str, '\0', strLen);
        strcpy(str, person.str);
        return *this;
    }
private:
    char* str;
    int strLen;
};