blob: a39a179ce543a98ee2a17ca3301eaf381a0f9b89 (
plain) (
blame)
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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
|
# Голямата четворка
- Конструктор по подразбиране (конструктор без параметри)
- Конструктор за копиране
- Оператор =
- Деструктор
Да разгледаме следната структура:
```c++
struct Test
{
A obj1;
B obj2;
C obj3;
};
```
Понеже функциите (от голямата четворка) не са дефинирани в структурата, компилаторът ще създаде такива:
```c++
int main()
{
Test currentObject; //default constructor
Test object2(currentObject); //copy constructor
currentObject = object2; //operator =
} //destructor (x2)
```
Кодът се компилира успешно и функциите имат правилно поведение.
### Как работят дефинираните от компилатора функции?
Всяка една от тези функции **извиква 'рекурсивно' същите функции върху член-данните.**
#### Пример за конструктора по подразбиране:

#### Пример за деструктора:

#### Пример за копиращия конструктор:

### Проблем при функциите, генерирани от компилатора:
Да разгледаме следния код:
```c++
struct Person
{
PersonA(const char* name, int age)
{
this->name = new char[strlen(name) + 1];
strcpy(this->name, name);
this->age = age;
}
private:
char* name;
int age;
};
int main()
{
Person p1;
Person p2(p1);
}
```
Горното извикване на копиращия конструктор има **неправилно поведение**:

Това е **shallow copy**. В p2 са се копирали стойностите на p1, което довежда до споделяне на една и съща динамична памет.
В тази ситуация ще трябва да се имплементират експлицитно **копиращия конструктор, оператора за присвояване и деструктора**, защото генерираните от компилатора не биха работили правилно.
**Правилното поведение** на копиращия конструктор е следното:

### Собствена имплементация на функциите за копиране и деструктора
```c++
struct Person
{
Person(const char* name, int age) : name(nullptr), age(age)
{
setName(name);
setAge(age);
}
Person(const Person& other)
{
copyFrom(other); // копираме
}
Person& operator=(const Person& other)
{
if (this != &other)
{
free(); //трием
copyFrom(other); //копираме
}
return *this;
}
~Person()
{
free(); //трием
}
.
.
.
};
```
При всички класове, които използват динамична памет, тези функции изглеждат по този начин. Разликите са в имплементациите на функциите **free** и **copyFrom**.
|