勤能补拙,厚积薄发

合抱之木,生于毫末;九层之台,起于垒土;千里之行,始于足下
随笔 - 19, 文章 - 0, 评论 - 3, 引用 - 0
数据加载中……

More Effective C++ (item29, part2)

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”功能类分离,达到复用功能类的功效。

posted on 2011-12-20 10:28 lee007 阅读(256) 评论(0)  编辑 收藏 引用


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   博问   Chat2DB   管理