The base class of reference counting
the base class of RCObject(reference counting) and RCPtr(smart point)
1 #include <string.h>
2
3 class RCObject {
4 public:
5 void addReference();
6 void removeReference();
7 void markUnshareable();
8 bool isShareable() const;
9 bool isShared() const;
10 protected:
11 RCObject();
12 RCObject(const RCObject& rhs);
13 RCObject& operator=(const RCObject& rhs);
14 virtual ~RCObject() = 0;
15 private:
16 int refCount;
17 bool shareable;
18 };
19
20 RCObject::RCObject()
21 : refCount(0), shareable(true)
22 {
23 }
24
25 RCObject::~RCObject()
26 {
27 }
28
29 RCObject::RCObject(const RCObject& rhs)
30 : refCount(0), shareable(true)
31 {
32 }
33
34 RCObject& RCObject::operator=(const RCObject& rhs)
35 {
36 return *this;
37 }
38
39 void RCObject::addReference()
40 {
41 ++refCount;
42 }
43
44 void RCObject::removeReference()
45 {
46 if (--refCount == 0) delete this;
47 }
48
49 bool RCObject::isShareable() const
50 {
51 return shareable;
52 }
53
54 bool RCObject::isShared() const
55 {
56 return refCount > 1;
57 }
58
59 void RCObject::markUnshareable()
60 {
61 shareable = false;
62 }
63
64
65 template<class T>
66 class RCPtr{
67 public:
68 RCPtr(T* realPtr = 0);
69 RCPtr(const RCPtr& rhs);
70 ~RCPtr();
71
72 RCPtr& operator=(const RCPtr& rhs);
73
74 T* operator->() const;
75 T& operator*() const;
76 private:
77 T* pointee;
78 void init();
79 };
80
81 template <class T>
82 RCPtr<T>::RCPtr(T* realPtr)
83 : pointee(realPtr)
84 {
85 init();
86 }
87
88 template <class T>
89 RCPtr<T>::RCPtr(const RCPtr& rhs)
90 : pointee(rhs.pointee)
91 {
92 init();
93 }
94
95 template <class T>
96 void RCPtr<T>::init()
97 {
98 if (pointee == 0) {
99 return;
100 }
101 if (pointee->isShareable() == false) {
102 pointee = new T(*pointee);
103 }
104 pointee->addReference();
105 }
106
107 template <class T>
108 RCPtr<T>& RCPtr<T>::operator=(const RCPtr& rhs)
109 {
110 if (rhs.pointee != pointee) {
111 if (pointee->isShared()) {
112 pointee->removeReference();
113 }
114 pointee = rhs.pointee;
115 init();
116 }
117 return *this;
118 }
119
120 template <class T>
121 RCPtr<T>::~RCPtr()
122 {
123 if (pointee) {
124 pointee->removeReference();
125 }
126 }
127
128 template <class T>
129 T* RCPtr<T>::operator->() const
130 {
131 return pointee;
132 }
133
134 template <class T>
135 T& RCPtr<T>::operator*() const
136 {
137 return *pointee;
138 }
139
the class of String
1 #include "RCObject.hpp"
2 #include <string.h>
3
4 class String {
5 public:
6 String(const char *initvalue = "");
7 const char& operator[](int index) const;
8 char& operator[](int index);
9 private:
10 struct StringVal : public RCObject {
11 char *data;
12 StringVal(const char *initvalue);
13 StringVal(const StringVal& rhs);
14 void init(const char *initvalue);
15 ~StringVal();
16 };
17 RCPtr<StringVal> value;
18 };
19
20 String::StringVal::StringVal(const char* initvalue)
21 {
22 init(initvalue);
23 }
24
25 String::StringVal::StringVal(const StringVal& rhs)
26 {
27 init(rhs.data);
28 }
29
30 String::StringVal::~StringVal()
31 {
32 delete []data;
33 }
34
35 void String::StringVal::init(const char* initvalue)
36 {
37 data = new char[strlen(initvalue) + 1];
38 strcpy(data, initvalue);
39 }
40
41 String::String(const char *initvalue)
42 :value(new StringVal(initvalue))
43 {
44 }
45
46 const char& String::operator[](int index) const
47 {
48 return value->data[index];
49 }
50
51 char& String::operator[](int index)
52 {
53 if (value->isShared()) {
54 value = new StringVal(value->data);
55 }
56 value->markUnshareable();
57 return value->data[index];
58 }
59
尚未写测试例子,仅仅用编译器验证了语法
该部分的机制就是将reference counting(RC) & smart point独立出来
在应用类(class String)定义一个中间量struct StringVal并使之继承自RCObject(RC class)从而拥有计数功能
然后将其指针包含于智能指针(smart point)类中,从而实现应用类与“reference counting(RC) & smart point”功能类分离,达到复用功能类的功效。