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 }

 

posted @ 2016-09-20 16:27  Kjing  阅读(472)  评论(0编辑  收藏  举报