refence counting
引用计数是C++中的常用计数,这里补全了文中的String类,并写了测试代码,已在gcc 4.4.1下编译通过
String.hpp文件内容如下:
1 #include <string.h>
2 #include <iostream>
3 class String {
4 friend bool operator==(const String& lhs, const String& rhs);
5 friend std::istream& operator>>(std::istream& in, const String& rhs);
6 friend std::ostream& operator<<(std::ostream& out, const String& rhs);
7 public:
8 String();
9 String(const char* value = "");
10 String(const String&);
11 ~String();
12 const char& operator[](int index) const;
13 char& operator[](int index);
14 String operator=(const String& rhs);
15 String& operator+=(const String& rhs);
16 private:
17 struct StringVal {
18 char* data;
19 int refCount;
20 bool shareable;
21 StringVal(const char* initValue);
22 ~StringVal();
23 };
24 StringVal* value;
25 };
26
27 String operator+(const String& lhs, const String& rhs);
28 bool operator==(const String& lhs, const String& rhs);
29 std::ostream& operator<<(std::ostream& out, const String& rhs);
30 std::istream& operator>>(std::istream& in, const String& rhs);
31
32 String::StringVal::StringVal(const char* initValue)
33 : refCount(1), shareable(true)
34 {
35 data = new char[strlen(initValue)+1];
36 strcpy(data, initValue);
37 }
38
39 String::StringVal::~StringVal()
40 {
41 delete []data;
42 }
43
44 String::~String()
45 {
46 if (--(value->refCount) == 0) {
47 delete value;
48 }
49 }
50
51 String::String(const char* value)
52 :value(new StringVal(value))
53 {
54 }
55
56 String::String(const String& rhs)
57 {
58 if (rhs.value->shareable) {
59 value = rhs.value;
60 ++(value->refCount);
61 } else {
62 value = new StringVal(rhs.value->data);
63 }
64 }
65
66 String String::operator=(const String& rhs)
67 {
68 if (rhs.value == value) {
69 return *this;
70 }
71 if (--(value->refCount) == 0) {
72 delete value;
73 }
74 value = rhs.value;
75 ++(value->refCount);
76 return *this;
77 }
78
79 const char& String::operator[](int index) const
80 {
81 return value->data[index];
82 }
83
84 char& String::operator[](int index)
85 {
86 if (value->refCount > 1) {
87 --(value->refCount);
88 value = new StringVal(value->data);
89 }
90 value->shareable = false;
91 return value->data[index];
92 }
93
94 bool operator==(const String& lhs, const String& rhs)
95 {
96 return lhs.value == rhs.value;
97 }
98
99 String operator+(const String& lhs, const String& rhs)
100 {
101 String tmp(lhs);
102 tmp += rhs;
103 return tmp;
104 }
105
106 String& String::operator+=(const String& rhs)
107 {
108 char *p = new char[strlen(value->data) + strlen(rhs.value->data) + 1];
109 strcpy(p, value->data);
110 strcat(p, rhs.value->data);
111 if (--(value->refCount) == 0) {
112 delete value;
113 }
114 this->value = new StringVal(p);
115 return *this;
116 }
117
118 std::ostream& operator<<(std::ostream& out, const String& rhs)
119 {
120 out << rhs.value->data;
121 return out;
122 }
123
124 std::istream& operator>>(std::istream& in, const String& rhs)
125 {
126 in >> rhs.value->data;
127 return in;
128 }
129
test.cpp文件内容如下:
#include "String.hpp"
using std::cout;
using std::endl;
int main()
{
String s1("More Effective C++");
String s2(s1);
String s3 = s1;
char c = s1[9];
s1[3] = 'c';
cout << "s1[9] = "<< c << endl;
if (s1 == s3) {
cout << "s1 == s3" << endl;
} else {
cout << "s1 has changed, but not s3\n"
<< "s1 = " << s1 << "\n"
<< "s3 = " << s3 << endl;
}
s2 += s1;
s3 = s1 + " and " + s2;
cout << "s2 + s1 = " << s2 << endl;
cout << "s3 = " << s3 << endl;
return 0;
}
运行程序的结果如下:
另外书中还提到了写一个基类来作为引用类基础,下篇继续