More Effective C++ 30. Proxy classes

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 RCObject
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; }


// the implementation of RCPtr
template<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::StringValue
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; }

// the implement of String
String::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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值