目录
实验代码
String.h
String.cpp
main.cpp主函数
实验总结
测试代码
主要任务:
创建一个String来进行以下测试
int main()
{
String s1("help!"), s2("Good!"), s3(s2), s4, s5;
cout << "s1=" << s1 << endl;//s1=help!
s3 = "help!";
cout << "s3=" << s3 << endl;//s3=help!
s3 = s2;
cout << "s3=" << s3 << endl;//s3=Good!
s3 += s2;
cout << "s3=" << s3 << endl;//s3=Good!Good!
cin >> s4;//输入jobs
cout << "s4=" << s4 << endl;//s4=jobs
s5 = s3+s4;
cout << "s5=" << s5 << endl;//s5=Good!Good!jobs
s5 = 'g';
cout << "s5=" << s5 << endl;//s5=g
cout << "strlen(s5)=" << s5.Length() << endl;//strlen(s5)=1
cout << boolalpha << (s3 == s1) << endl;//s3=Good!Good!和s1=help! 返回false
cout << boolalpha << (s3 < s1) << endl;//成立返回true
return 0;
}
实验代码
String.h
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#pragma once #include<iostream> using namespace std; class String { public: friend ostream& operator<<(ostream& os, String& c); friend istream& operator>>(istream& is, String& c); String(); String(const char* s); //复制构造 String(String& ss); //移动构造函数 String(String&& s)noexcept; //返回字符串长度 int Length(); //重载=,传入字符串 String& operator =(const char*c); //重载=,深复制 String& operator =(String& c); //重载= 移动构造 String& operator=(String&& c); //重载= 传入单个字符 String& operator=(char c); //重载+= 连接字符串 String& operator+=(String& c); //重载+ String operator + (String & c); //重载[] char operator[](int i); //重载== bool operator==(String& c); //重载< bool operator<(String& c); ~String() { if (this->m_str != NULL) { delete m_str; m_str = NULL; } } private: char* m_str; int m_size;//含有的长度 };
String.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
119
120
121
122
123
124
125
126
127
128
129
130#include"String.h" String::String():m_size(0) { this->m_str = new char(); } //有参构造 String::String(const char* s ): m_size(strlen(s)) { this->m_str = new char[this->m_size+1]; //strcpy_s(m_str, m_size+1, s); strcpy(m_str, s); } //复制构造 String::String(String& ss):m_size(ss.Length()) { this->m_str = new char[m_size+1]; //strcpy_s(m_str, m_size+1, ss.m_str); strcpy(m_str, ss.m_str); } //移动构造函数 String::String(String&& s)noexcept { this->m_size = s.m_size; this->m_str = new char[this->m_size + 1]; strcpy(this->m_str, s.m_str); } //重载[] char String::operator[](int i) { return this->m_str[i]; } //重载== bool String::operator==(String& c) { if (strcmp(this->m_str, c.m_str))//不相等时,返回非0,进入if return false; return true; } //重载< bool String::operator<(String& c) { if (strcmp(this->m_str, c.m_str) < 0) return true; return false; } //赋值传入字符串 String& String::operator=(const char* c) { this->m_size = strlen(c); this->m_str = new char[this->m_size + 1]; strcpy(this->m_str, c); return *this; } //重载=,深复制 String& String::operator =(String& c) { this->m_size = c.Length(); this->m_str = new char[m_size+1]; strcpy(this->m_str, c.m_str); return *this; } //重载= 移动构造 String& String::operator=(String&& c) { this->m_size = c.Length(); this->m_str = new char[m_size + 1]; strcpy(this->m_str, c.m_str); return *this; } //重载= 传入单个字符 String& String::operator=(char c) { this->m_size = 1; this->m_str = new char[2]; this->m_str[0] = c; this->m_str[1] = ''; return *this; } //重载+= 连接字符串 String& String::operator+=(String& c) { this->m_size += c.m_size;//更新空间值 char* temp= strcat(this->m_str, c.m_str);//连接后赋值临时变量 this->m_str = new char[this->m_size + 1];//开辟新空间 strcpy(this->m_str, temp);//赋值 return *this; } //重载+ String String::operator + (String& c) { String temp; temp.m_size = this->m_size + c.m_size; temp.m_str = new char[temp.m_size + 1]; strcpy(temp.m_str, this->m_str); strcat(temp.m_str, c.m_str); return temp; } //返回字符串长度 int String::Length() { return this->m_size; } //重载<< ostream& operator<<(ostream &os, String& c) { os << c.m_str; return os; } istream& operator>>(istream& is, String& c) { /*第一想法(错),创建一个String s; 时, 由于默认构造,分配空间0,因此后输入的话空间不足,输出会报错,无法分配*/ //is>>c.m_str; // return is; /*第二想法(对),可以先创建一个对象,空间给足够,输入值后,调整指针和空间大小后赋值给c,但缺点是 创建一个比较大的对象空间开销太大,导致浪费*/ //String temp; //temp.m_str = new char[1000]; //is >> temp.m_str; //temp.m_size = strlen(temp.m_str); //c = temp; /*思考了一下,可以先输入字符串,创建临时字符串指针存储,c的空间为temp的大小, 开辟空间为size+1,之后把这个临时的字符串赋值给c,这样开销最小,动态分配*/ is >> c.m_str; const char* temp = c.m_str; c.m_size = strlen(temp); c.m_str = new char[c.m_size + 1]; strcpy(c.m_str,temp); return is; }
main.cpp主函数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22#include"String.h" int main() { String s1("help!"), s2("Good!"), s3(s2), s4, s5; cout << "s1=" << s1 << endl;//s1=help! s3 = "help!"; cout << "s3=" << s3 << endl;//s3=help! s3 = s2; cout << "s3=" << s3 << endl;//s3=Good! s3 += s2; cout << "s3=" << s3 << endl;//s3=Good!Good! cin >> s4;//jobs cout << "s4=" << s4 << endl;//s4=jobs s5 = s3+s4; cout << "s5=" << s5 << endl;//s5=Good!Good!jobs s5 = 'g'; cout << "s5=" << s5 << endl;//s5=g cout << "strlen(s5)=" << s5.Length() << endl;//strlen(s5)=1 cout << boolalpha << (s3 == s1) << endl;//s3=Good!Good!和s1=help! 返回false cout << boolalpha << (s3 < s1) << endl;//成立返回true return 0; }
实验总结
总结一下,容易出现内存分配不足问题,重载>>时动态分配,由于内部存在指针,所以析构时会清除指针,要进行深复制(防止堆区的数据被释放两次,这个会报错),重载的时候要注意时返回String还是String&,很有影响,String& 返回本身因此可以链式操作,String则不可以,然后注意重载各种操作符号即可完成此测试。
测试代码
s4输入jobs截图如下:
最后
以上就是独特绿草最近收集整理的关于String 类的封装C++的全部内容,更多相关String内容请搜索靠谱客的其他文章。
发表评论 取消回复