More Effective C++ 30. Proxy classes

来源:互联网 发布:hbuilder 商城app源码 编辑:程序博客网 时间:2024/06/05 07:13
template<class T>class Array2D {public:    Array2D(int d1, int d2):dim(d2) {        data = (T*) malloc(sizeof(T) * d1 *d2);    }    class Array1D {    public:        Array1D (T* pd) : data(pd) { }        T& operator[] (int index) {            return *(data + index);        }        T* data;    };    Array1D operator[] (int index) {        return Array1D(data + dim * index);    }private:    size_t dim;    T* data;};
template<class T>class RCPtr {public:    RCPtr(T* realPtr = 0);    RCPtr(const RCPtr& rhs);    ~RCPtr();    RCPtr& operator=(const RCPtr& rhs);    T* operator->() const;    T& operator*() const;private:    T* pointee;    void init();};class RCObject {public:    RCObject();    RCObject(const RCObject& rhs);    RCObject& operator=(const RCObject& rhs);    virtual ~RCObject() = 0;    void addReference();    void removeReference();    void markUnshareable();    bool isShareable() const;    bool isShared() const;private:    size_t refCount;    bool shareable;};class String {public:    String(const char *value = "");    class CharProxy {    public:        CharProxy(String& str, int index);        CharProxy& operator=(const CharProxy& rhs);        CharProxy& operator=(char c);        operator char() const;        const char * operator&() const;         char * operator&();    private:        String& theString;        int charIndex;    };    const CharProxy operator[](int index) const;    CharProxy operator[] (int index);    // friend class CharProxy;private:    struct StringValue :public RCObject {        char *data;        StringValue(const char *initValue);        StringValue(const StringValue& rhs);        void init(const char *initValue);        ~StringValue();    };    RCPtr<StringValue> value;};// the implementation of RCObjectRCObject::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; }// the implementation of RCPtrtemplate<class T>void RCPtr<T>::init() {    if (pointee == 0) 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() { if (pointee) pointee->removeReference(); }template<class T>RCPtr<T>& RCPtr<T>::operator=(const RCPtr& rhs) {    if (pointee != rhs.pointee) {        T* oldPointee = pointee;        pointee = rhs.pointee;        init();        if (oldPointee) oldPointee->removeReference();    }    return *this;}template<class T>T* RCPtr<T>::operator->() const { return pointee; }template<class T>T& RCPtr<T>::operator*() const { return *pointee; }// the implement of String::StringValuevoid 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; }// the implement of StringString::String(const char *initValue) : value(new StringValue(initValue)) { }const String::CharProxy String::operator[](int index) const { return String::CharProxy(const_cast<String&>(*this), index); }String::CharProxy String::operator[] (int index) { return String::CharProxy(*this, index); }String::CharProxy::CharProxy(String& str, int index) : theString(str), charIndex(index) { }String::CharProxy& String::CharProxy::operator=(const CharProxy& rhs) {    if (theString.value->isShareable()) {        theString.value = new StringValue(theString.value->data);    }    theString.value->data[charIndex] = rhs.theString.value->data[rhs.charIndex];    return *this;}String::CharProxy& String::CharProxy::operator=(char c) {    if (theString.value->isShared()) {        theString.value = new StringValue(theString.value->data);    }    theString.value->markUnshareable();    theString.value->data[charIndex] = c;    return *this;}String::CharProxy::operator char()  const {    return theString.value->data[charIndex];}char * String::CharProxy::operator&() {    if (theString.value->isShared()) {        theString.value = new StringValue(theString.value->data);    }    return theString.value->data + charIndex;}const char * String::CharProxy::operator&() const {    return theString.value->data + charIndex;}