-
Notifications
You must be signed in to change notification settings - Fork 0
/
copying.cpp
109 lines (94 loc) · 3.01 KB
/
copying.cpp
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
// https://www.youtube.com/watch?v=BvR1Pgzzr38&list=PLlrATfBNZ98dudnM48yfGUldqGD0S4FFb&index=44&t=25s&ab_channel=TheCherno
#include <iostream>
#include <string.h>
struct Vector2
{
int x, y;
};
struct NoCopy
{
int value;
// disable copy constructor
// this prevents copying by value
NoCopy(const NoCopy &other) = delete;
};
class String
{
public:
String(const char *string)
{
m_Size = strlen(string);
m_Buffer = new char[m_Size + 1];
memcpy(m_Buffer, string, m_Size);
m_Buffer[m_Size] = 0; // null terminator at the end
std::cout << "Created string!" << std::endl;
}
// deep copy constructor instead of default shallow copy constructor
String(const String &other)
: m_Size(other.m_Size)
{
// the reason we need to do this is because
// the default copy constructor only copies the pointer
// this means that both objects will point to the same data
// if one object is destroyed, the other object will have a dangling pointer
// if one object changes data, the other object will be affected
// this would be called a shallow copy
// we want to do a deep copy:
m_Buffer = new char[m_Size + 1];
memcpy(m_Buffer, other.m_Buffer, m_Size + 1);
std::cout << "Copied string!" << std::endl;
}
~String()
{
delete[] m_Buffer;
std::cout << "Destroyed string!" << std::endl;
}
const char *GetValue() const
{
return m_Buffer;
}
char &operator[](unsigned int index)
{
return m_Buffer[index];
}
private:
char *m_Buffer;
unsigned int m_Size;
};
std::ostream &operator<<(std::ostream &stream, const String &other)
{
stream << other.GetValue();
return stream;
}
int main()
{
{ // copying
int value = 3;
int copy = value; // changing copy doesn't affect value
Vector2 vector1 = {1, 2};
Vector2 vector2 = vector1;
vector2.x = 5; // changing vector2 doesn't affect vector1
// vector1.x is still 1
}
{ // not copying (reference)
int value = 3;
int &reference = value; // reference is an alias for value
Vector2 vector1 = {1, 2};
Vector2 &vector2 = vector1; // vector2 is an alias for vector1
vector2.x = 5; // changing vector2 changes vector1
// vector1.x is now 5
}
{ // not copying (pointers)
int value = 3;
int *pointer = &value; // pointer points to address of value
Vector2 vector1 = {1, 2};
Vector2 *vector2 = &vector1; // vector2 points to address of vector1
vector2->x = 5; // changing vector2 changes vector1
// vector1.x is now 5
}
String str1 = "Hello";
String str2 = str1; // copy constructor
str2[1] = 'a'; // change value of str2 to see if str1 is affected
std::cout << str1 << std::endl;
std::cout << str2 << std::endl;
}