带引用计数的String类简单实现

很好的一个示范例子,设计到类设计,模版,继承,封装。

麻雀虽小五脏俱全,废话少说,来看代码:

主程序:

 1 #include <iostream>
 2 
 3 #include "rcstring.h"
 4 
 5 int main(void)
 6 {
 7     String s("hello");
 8 
 9     std::cout << s[2] << std::endl;
10 
11     std::cout << "Hello World!" << std::endl;
12 
13     return 0;
14 }

String声明和实现:

 1 //rcstring.h
 2 #include "rcobject.h"
 3 #include "rcptr.h"
 4 
 5 class String {
 6 public:
 7     String(const char *value = "");
 8     const char& operator[] (int index) const;
 9     char & operator[] (int index);
10 private:
11     struct StringValue: public RCObject {
12         StringValue(const char *initValue);
13         StringValue(const StringValue &rhs);
14         ~StringValue();
15 
16         void init(const char *initValue);
17 
18         char *data;
19     };
20 
21     RCPtr<StringValue> value;
22 };
23 
24 //rcstring.cpp
25 #include "rcstring.h"
26 #include <cstring>
27 
28 String::String(const char *initValue)
29     :value(new StringValue(initValue))
30 {
31 
32 }
33 
34 const char& String::operator[] (int index) const
35 {
36     return value->data[index];
37 }
38 
39 char& String::operator[] (int index)
40 {
41     if(value->isShared())
42         value = new StringValue(value->data);
43 
44     value->markUnshareable();
45 
46     return value->data[index];
47 }
48 
49 String::StringValue::StringValue(const char *initValue)
50 {
51     init(initValue);
52 }
53 
54 String::StringValue::StringValue(const StringValue& rhs)
55 {
56     init(rhs.data);
57 }
58 
59 String::StringValue::~StringValue()
60 {
61     delete [] data;
62 }
63 
64 void String::StringValue::init(const char *value)
65 {
66     data = new char[strlen(value) + 1];
67     strcpy(data, value);
68 }

引用计数类rcobject:

 1 //rcobject.h
 2 
 3 class RCObject {
 4 protected:
 5     RCObject();
 6     RCObject(const RCObject &rhs);
 7     RCObject& operator=(const RCObject &rhs);
 8     virtual ~RCObject() = 0;
 9 
10 public:
11     void addReference();
12     void removeReference();
13     void markUnshareable();
14     bool isShareable() const;
15     bool isShared() const;
16 private:
17     int refCount;
18     bool shareable;
19 };
20 
21 
22 //rcobject.cpp
23 #include "rcobject.h"
24 
25 RCObject::RCObject()
26     : refCount(0), shareable(true)
27 {
28 
29 }
30 
31 RCObject::RCObject(const RCObject &rhs)
32     :refCount(0), shareable(true)
33 {
34 
35 }
36 
37 RCObject& RCObject::operator=(const RCObject &rhs)
38 {
39     return *this;
40 }
41 
42 RCObject::~RCObject()
43 {
44 
45 }
46 
47 void RCObject::addReference()
48 {
49     ++refCount;
50 }
51 
52 void RCObject::removeReference()
53 {
54     if(--refCount == 0) delete this;
55 }
56 
57 void RCObject::markUnshareable()
58 {
59     shareable = false;
60 }
61 
62 bool RCObject::isShareable() const
63 {
64     return shareable;
65 }
66 
67 bool RCObject::isShared() const
68 {
69     return refCount > 1;
70 }

用来管理rcstring属性的简单智能指针:

 1 //rcptr.h
 2 
 3 template <typename T>
 4 class RCPtr {
 5 public:
 6     RCPtr(T *realPtr = 0);
 7     RCPtr(const RCPtr &rhs);
 8     ~RCPtr();
 9 
10 public:
11     RCPtr& operator= (const RCPtr &rhs);
12     T* operator-> ()const;
13     T& operator* ()const;
14 
15 private:
16     T *pointee;
17     void init();
18 };
19 
20 template <typename T>
21 RCPtr<T>::RCPtr(T *realPtr)
22     :pointee(realPtr)
23 {
24     init();
25 }
26 
27 template <typename T>
28 RCPtr<T>::RCPtr(const RCPtr& rhs)
29     :pointee(rhs.pointee)
30 {
31     init();
32 }
33 
34 template <typename T>
35 RCPtr<T>& RCPtr<T>::operator=(const RCPtr& rhs)
36 {
37     if(pointee != rhs.pointee) {
38         if(pointee) pointee->removeReference();
39 
40         pointee = rhs.pointee;
41 
42         init();
43     }
44 
45     return *this;
46 }
47 
48 template <typename T>
49 RCPtr<T>::~RCPtr()
50 {
51     if(pointee) pointee->removeReference();
52 }
53 
54 template <typename T>
55 T* RCPtr<T>::operator-> () const 
56 {
57     return pointee;
58 }
59 
60 template <typename T>
61 T& RCPtr<T>::operator* () const
62 {
63     return *pointee;
64 }
65 
66 template <typename T>
67 void RCPtr<T>::init()
68 {
69     if(pointee == 0) return;
70     if(pointee->isShareable() == false)
71         pointee = new T(*pointee);
72 
73     pointee->addReference();
74 }

 

posted @ 2013-01-15 15:47  Jojodru  阅读(648)  评论(0编辑  收藏  举报