-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathCherno89-90.cpp
118 lines (101 loc) · 2.81 KB
/
Cherno89-90.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
110
111
112
113
114
115
116
117
118
// 【89】【Cherno C++】【中字】C++移动语义
// 【90】【Cherno C++】【中字】stdmove与移动赋值操作符
// 参考博客:https://www.cnblogs.com/zhangyi1357/p/16018810.html
// 三法则:如果需要析构函数,则一定需要拷贝构造函数和拷贝赋值操作符
// 五法则:为了支持移动语义,又增加了移动构造函数和移动赋值运算符
// 依赖C++11引入的右值引用
#include <iostream>
#include <cstring>
class String
{
public:
String() = default;
String(const char *string)
{
printf("Created!\n");
m_Size = strlen(string);
m_Data = new char[m_Size];
memcpy(m_Data, string, m_Size);
}
String(const String &other)
{
printf("Copied!\n");
m_Size = other.m_Size;
m_Data = new char[m_Size];
memcpy(m_Data, other.m_Data, m_Size);
}
String(String &&other) // 移动构造函数
{
printf("Moved!\n");
m_Size = other.m_Size;
m_Data = other.m_Data;
other.m_Data = nullptr;
other.m_Size = 0; // 偷掉原来的String
}
~String()
{
printf("Destroyed!\n");
delete[] m_Data;
}
void Print()
{
for (uint32_t i = 0; i < m_Size; ++i)
printf("%c", m_Data[i]);
printf("\n");
}
String &operator=(String &&other) // 移动复制运算符重载
{
printf("Moved\n");
if (this != &other)
{
delete[] m_Data;
m_Size = other.m_Size;
m_Data = other.m_Data;
other.m_Data = nullptr;
other.m_Size = 0;
}
return *this;
}
private:
char *m_Data;
uint32_t m_Size;
};
class Entity
{
public:
Entity(const String &name) : m_Name(name) {}
// 接受右值的函数在参数传进来后其右值属性就退化了,
// 所以这里给m_Name的参数仍然是左值,还是会调用复制构造函数。
// Entity(String &&name) : m_Name(name) {}
// 可以通过强制类型转换实现
// Entity(String &&name) : m_Name((String &&) name) {}
// 更好的方法是通过std::move实现
Entity(String &&name) : m_Name(std::move(name)) {}
void PrintName() { m_Name.Print(); }
private:
String m_Name;
};
int main(int argc, const char *argv[])
{
{
Entity entity(String("Cherno"));
entity.PrintName();
}
std::cout << "- - - - - -\n";
String string = "Hello";
String dest = std::move(string);
std::cout << "- - - - - -\n";
String apple = "apple";
String orange = "orange";
printf("apple: ");
apple.Print();
printf("orange: ");
orange.Print();
apple = std::move(orange);
printf("apple: ");
apple.Print();
printf("orange: ");
orange.Print();
std::cout << "- - - - - -\n";
return 0;
}