Effective C++ 一个简单的 String 类的 Reference Counting 实现(C++)

来源:互联网 发布:淘宝抢购软件 编辑:程序博客网 时间:2024/06/06 01:54
// Reference-counting pointertemplate<class T>class RCPtr{public:RCPtr(T* realPtr = nullptr);RCPtr(const RCPtr& rhs);~RCPtr();RCPtr& operator = (const RCPtr& rhs);T* operator-> () const;T& operator* () const;private:T* pointee;void init();};template<class T>void RCPtr<T>::init(){if (pointee == nullptr) return;if (pointee->isShareable() == false){pointee = new T(*pointee);}pointee->addReference();}template<class T>RCPtr<T>::RCPtr(T* realPtr): pointee(realPtr){init();}template<class T>RCPtr<T>::RCPtr(const RCPtr& rhs): pointee(rhs.pointee){init();}template<class T>RCPtr<T>& RCPtr<T>::operator = (const RCPtr& rhs){if (pointee != rhs.pointee){if (pointee){pointee->removeReference();}pointee = rhs.pointee;init();}return *this;}template<class T>RCPtr<T>::~RCPtr(){if (pointee){pointee->removeReference();}}template<class T>T* RCPtr<T>::operator -> () const{return pointee;}template<class T>T& RCPtr<T>::operator * () const{return *pointee;}// Reference-counting objectclass RCObject{protected:RCObject();RCObject(const RCObject& rhs);RCObject& operator = (const RCObject& rhs);virtual ~RCObject() = 0;public:void addReference();void removeReference();void markUnshareable();bool isShareable() const;bool isShared() const;private:int refCount;bool shareable;};RCObject::RCObject(): refCount(0), shareable(true){}RCObject::RCObject(const RCObject&): refCount(0), shareable(true){}RCObject& RCObject::operator=(const RCObject&){return *this;}RCObject::~RCObject() {}void RCObject::addReference(){++refCount;}void RCObject::removeReference(){if (--refCount == 0){delete this;}}void RCObject::markUnshareable(){shareable = false;}bool RCObject::isShareable() const{return shareable;}bool RCObject::isShared() const{return refCount > 1;}// String classclass String{public:String(const char* initValue = "");const char& operator [] (int index) const;char& operator [] (int index);friend ostream& operator << (ostream& lhs, const String& rhs);private:struct StringValue : public RCObject{char *data;StringValue(const char* initValue);StringValue(const StringValue& rhs);void init(const char *initValue);~StringValue();};RCPtr<StringValue> value;};void String::StringValue::init(const char* initValue){data = new char[strlen(initValue) + 1];strcpy(data, initValue);}String::StringValue::StringValue(const char* initValue){init(initValue);}String::StringValue::StringValue(const StringValue& rhs){init(rhs.data);}String::StringValue::~StringValue(){delete[] data;}String::String(const char* initValue): value(new StringValue(initValue)){}const char& String::operator [] (int index) const{return value->data[index];}char& String::operator[](int index){if (value->isShared()){value = new StringValue(value->data);}value->markUnshareable();return value->data[index];}ostream& operator << (ostream& lhs, const String& rhs){lhs << rhs.value->data;return lhs;}

0 0