带引用计数的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 }