技术: 带有移动语义的 C++ 字符串类

作为右值探讨的一部分, 单独拉出来, 方便加深认识

本文是右值相问题的补充, 这里主要实现一个有右值语义的字符串类

其代码实现, 大致如下:

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
class MyString
{
private:
char *_data;
size_t _len;

//only deal with data part
void _init_data(const char* s)
{
_data = new char[_len+1];
memcpy(_data, s, _len);
_data[_len] = '\0';
}

public:
//default
MyString() : _data(NULL), _len(0) {}

//constructor
MyString(const char *p) : _len(strlen(p)) {
_init_data(p);
}

//copy constructor
MyString(const MyString& str) : _len(str._len)
{
_init_data(str._data);
}

//copy assigment
MyString& operator=(const MyString&str)
{
if(this != &str) {
if(_data) {
delete _data;
}
_len = str._len;
_init_data(str._data);
}
return *this;
}


//move constructor
MyString(MyString&& str) noexcept :
_data(str._data), _len(str._len) {

str._len = 0;
str._data = nullptr; //watchout double delete
}

//move assigment
MyString& operator=(MyString&& str) noexcept
{
if(this != & str) {
if(_data) {
delete _data;
}
_len = str._len;
_data = str._data; //MOVE

str._len = 0;
str._data = nullptr;
}

return *this;
}

//deconstructor
virtual ~MyString()
{
if(_data) {
delete _data;
}
}

//为了放入一些有序容器中, 需要下面的函数
//compare
bool operator<(const MyString& str) const
{
//借用std::string的比较函数
return std::string(this->_data) < string(str._data);
}

//==
bool operator==(const MyString& str)
{
return std::string(this->_data) == std::string(str._data);
}

//get , c_str()
char *get() const {return _data;}
};

//一般还要提供一个 MyStringHashCodeFunctor函数对象用于hash容器, 或者借助标准库的`std::hash`仿函数模板特化一个属于MyString的特化模板仿函数.
//例如下面

namespace std
{//一定要放在std下
template<>
struct hash<MyString>
{
size_t operator(const MyString& s) const noexcept()
{
return hash<string>()(string(s.get()));
}
}

};

实现非常简单, 像operator<<()这样的不相关的函数则省略了.

|