MyString
【摘自C++程序设计语言】
MyString.h
1 #include <cstring> 2 #include <iostream> 3 #include <stdexcept> 4 5 #ifndef _MYSTRING 6 #define _MYSTRING 7 8 class MyString 9 { 10 public: 11 MyString(); 12 MyString(const char* p); 13 14 MyString(const MyString& x); 15 MyString& operator=(const MyString& x); 16 17 MyString(MyString&& x); 18 MyString& operator=(MyString&& x); 19 20 ~MyString() 21 { 22 if (short_max < sz) 23 delete[] ptr; 24 } 25 26 char& operator[](int n) { return ptr[n]; } 27 char operator[](int n) const { return ptr[n]; } 28 29 char& at(int n) { check(n); return ptr[n]; } 30 char at(int n) const { check(n); return ptr[n]; } 31 32 MyString& operator+=(char c); 33 34 const char* c_str() { return ptr; } 35 const char* c_str() const { return ptr; } 36 37 int size() const { return sz; } 38 int capacity() const { return (sz <= short_max) ? short_max : sz + space; } 39 40 private: 41 void check(int n) const 42 { 43 if (n < 0 || sz <= n) 44 throw std::out_of_range("String::at()"); 45 } 46 47 char* expand(const char* ptr, int n) 48 { 49 char* p = new char[n]; 50 strcpy(p, ptr); 51 return p; 52 } 53 54 void copy_from(const MyString& x); 55 void move_from(MyString& x); 56 private: 57 static const int short_max = 15; 58 unsigned int sz; 59 char* ptr; 60 union { 61 int space; 62 char ch[short_max+1]; 63 }; 64 }; 65 66 std::ostream& operator<<(std::ostream& os, const MyString& s); 67 std::istream& operator>>(std::istream& is, MyString& s); 68 bool operator==(const MyString& a, const MyString& b); 69 bool operator!=(const MyString& a, const MyString& b); 70 char* begin(MyString& x); 71 char* end(MyString& x); 72 const char* begin(const MyString& x); 73 const char* end(const MyString& x); 74 MyString& operator+=(MyString& a, const MyString& b); 75 MyString operator+(const MyString& a, const MyString b); 76 77 #endif
MyString.cpp
1 #include "MyString.h" 2 using namespace std; 3 4 MyString::MyString() 5 : sz{0}, ptr{ch} 6 { 7 ch[0] = 0; 8 } 9 10 MyString::MyString(const char* p) 11 : sz{strlen(p)}, 12 ptr{(sz <= short_max) ? ch : new char[sz + 1]}, 13 space{0} 14 { 15 strcpy(ptr, p); 16 } 17 18 MyString::MyString(const MyString& x) 19 { 20 copy_from(x); 21 } 22 23 MyString& MyString::operator=(const MyString& x) 24 { 25 if (this == &x) return *this; 26 27 char* p = (short_max < sz) ? ptr : 0; 28 copy_from(x); 29 delete[] p; 30 return *this; 31 } 32 33 MyString::MyString(MyString&& x) 34 { 35 move_from(x); 36 } 37 38 MyString& MyString::operator=(MyString&& x) 39 { 40 if (this == &x) return *this; 41 42 if (short_max < sz) delete[] ptr; 43 move_from(x); 44 return *this; 45 } 46 47 MyString& MyString::operator+=(char c) 48 { 49 if (sz == short_max) { 50 int n = sz + sz + 2; 51 ptr = expand(ptr, n); 52 space = n - sz - 2; 53 } 54 else if (short_max < sz) { 55 if (space == 0) { 56 int n = sz + sz + 2; 57 char* p = expand(ptr, n); 58 delete[] ptr; 59 ptr = p; 60 space = n - sz - 2; 61 } 62 else { 63 --space; 64 } 65 } 66 ptr[sz] = c; 67 ptr[++sz] = 0; 68 69 return *this; 70 } 71 72 void MyString::copy_from(const MyString& x) 73 { 74 if (x.sz <= short_max) { 75 memcpy(this, &x, sizeof(x)); 76 ptr = ch; 77 } 78 else { 79 ptr = expand(x.ptr, sz + 1); 80 sz = x.sz; 81 space = 0; 82 } 83 } 84 85 void MyString::move_from(MyString& x) 86 { 87 if (x.sz <= short_max) { 88 memcpy(this, &x, sizeof(x)); 89 ptr = ch; 90 } 91 else { 92 ptr = x.ptr; 93 sz = x.sz; 94 space = x.space; 95 x.ptr = x.ch; 96 x.sz = 0; 97 x.ch[0] = 0; 98 } 99 } 100 101 ostream& operator<<(ostream& os, const MyString& s) 102 { 103 os << s.c_str(); 104 return os; 105 } 106 107 istream& operator>>(istream& is, MyString& s) 108 { 109 s = ""; 110 is >> ws; 111 char ch = ' '; 112 while (is.get(ch) && !isspace(ch)) { 113 s += ch; 114 } 115 return is; 116 } 117 118 bool operator==(const MyString& a, const MyString& b) 119 { 120 if (a.size() != b.size()) 121 return false; 122 for (int i = 0; i != a.size(); ++i) { 123 if (a[i] != b[i]) 124 return false; 125 } 126 return true; 127 } 128 129 bool operator!=(const MyString& a, const MyString& b) 130 { 131 return !(a == b); 132 } 133 134 char* begin(MyString& x) 135 { 136 return (char*)x.c_str(); 137 } 138 139 char* end(MyString& x) 140 { 141 return (char*)(x.c_str() + x.size()); 142 } 143 144 const char* begin(const MyString& x) 145 { 146 return x.c_str(); 147 } 148 149 const char* end(const MyString& x) 150 { 151 return x.c_str() + x.size(); 152 } 153 154 MyString& operator+=(MyString& a, const MyString& b) 155 { 156 for (auto x : b) { 157 a += x; 158 } 159 return a; 160 } 161 162 MyString operator+(const MyString& a, const MyString b) 163 { 164 MyString res{b}; 165 res += b; 166 return res; 167 }
Test.cpp
1 #include <iostream> 2 #include "MyString.h" 3 using namespace std; 4 5 int main() 6 { 7 MyString s("abcdefghij"); 8 cout << s << "\n"; 9 s += 'k'; 10 s += 'l'; 11 s += 'm'; 12 s += 'n'; 13 cout << s << "\n"; 14 15 MyString s2 = "Hell"; 16 s2 += " and high water"; 17 cout << s2 << "\n"; 18 19 MyString s3 = "qwerty"; 20 s3 = s3; 21 MyString s4 = "the quick brown fox jumped over the lazy dog"; 22 s4 = s4; 23 cout << s3 << " " << s4 << "\n"; 24 25 cout << s + "." + s3 + MyString(".") + "Horsefeathers\n"; 26 27 MyString buf; 28 while (cin >> buf && buf != "quit") { 29 cout << buf << " " << buf.size() << " " << buf.capacity() << "\n"; 30 } 31 }