More Effective C++笔记
代理类
实现二维数组[][]读取
#include <iostream>
using namespace std;
template<class T>
class Array2D
{
public:
class Array1D
{
public:
Array1D(int dim)
{
_arr = new T[dim];
for ( int i = 0; i < dim; ++i )
_arr[i] = 1.0;
}
//省去拷贝构造、拷贝赋值、析构实现
T& operator[](int index) { return _arr[index]; }
const T& operator[](int index) const { return _arr[index]; }
private:
T *_arr;
};
Array2D(int dim1, int dim2)
{
_data = (Array1D *)malloc(dim1 * sizeof(Array1D));
for (int i = 0; i < dim1; ++i)
{
_data[i] = Array1D(dim2);
}
}
//省去拷贝构造、拷贝赋值、析构实现
Array1D operator[](int index) { return _data[index]; }
const Array1D operator[](int index) const { return _data[index]; }
private:
Array1D *_data;
};
void testArray()
{
Array2D<float> data(10, 20);
//...
cout << data[3][6]; //1
}
区分通过operator[]进行的是读操作还是写操作
//=================================定义=================================
//RCPtr定义
template<class T>
class RCPtr
{
public:
RCPtr(T* realPtr = 0);
RCPtr(const RCPtr& rhs);
RCPtr& operator=(const RCPtr &rhs);
~RCPtr();
T* operator->() const;
T& operator*() const;
private:
void init();
T* _ptr;
};
//PCPtr实现
template<class T>
RCPtr<T>::RCPtr(T* realPtr) :_ptr(realPtr) { init(); }
template<class T>
RCPtr<T>::RCPtr(const RCPtr& rhs) : _ptr(rhs._ptr) { init(); };
template<class T>
RCPtr<T>& RCPtr<T>::operator=(const RCPtr<T> &rhs)
{
if (_ptr != rhs._ptr)
{
if (_ptr)
_ptr->removeReference();
_ptr = rhs._ptr;
init();
}
return *this;
}
template<class T>
RCPtr<T>::~RCPtr() { if (_ptr) _ptr->removeReference(); }
template<class T>
T* RCPtr<T>::operator->() const { return _ptr; }
template<class T>
T& RCPtr<T>::operator*() const { return *_ptr; }
template<class T>
void RCPtr<T>::init()
{
if (_ptr == 0)
return;
if (_ptr->isShareable() == false)
{
//_ptr类型是T(StringValue),依赖于T的拷贝构造函数
_ptr = new T(*_ptr);
}
_ptr->addReference();
}
//RCObject定义
class RCObject
{
public:
void addReference();
void removeReference();
void markUnshareable();
bool isShareable() const;
bool isShared() const;
protected:
RCObject();
RCObject(const RCObject &rhs);
RCObject& operator=(const RCObject &rhs);
virtual ~RCObject() = 0; //RCObject只能作为基类使用
private:
int _refCount;
bool _shareable;
};
//RCObject实现
RCObject::RCObject()
:_refCount(0), _shareable(true) {}
RCObject::RCObject(const RCObject &rhs)
: _refCount(0), _shareable(true) {}
RCObject& RCObject::operator=(const RCObject &rhs) { 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定义
class MyString
{
public:
class CharProxy
{
public:
CharProxy(MyString &str, int index);
CharProxy& operator=(const CharProxy &rhs); //lvalue
CharProxy& operator=(char c); //use
operator char() const; //rvalue use
private:
MyString& _theString;
int _charIndex;
};
MyString(const char * initVal = "");
//const char& operator[](int index) const;
//char& operator[](int index);
//注意:不加引用符号
const CharProxy operator[](int index) const;
CharProxy operator[](int index);
friend class CharProxy;
private:
struct StringValue : public RCObject
{
StringValue(const char *initVal);
StringValue(const StringValue &rhs);
~StringValue();
void init(const char *initVal);
char *_data;
};
RCPtr<StringValue> _value;
};
//=================================实现=================================
//MyString::StringValue实现
void MyString::StringValue::init(const char *initVal)
{
_data = new char[strlen(initVal) + 1];
strcpy(_data, initVal);
}
MyString::StringValue::StringValue(const char *initVal) { init(initVal); }
MyString::StringValue::StringValue(const StringValue &rhs) { init(rhs._data); }
MyString::StringValue::~StringValue() { delete[] _data; }
//MyString实现
MyString::MyString(const char * initVal)
:_value(new StringValue(initVal)) {}
#if 0
const char& MyString::operator[](int index) const
{
return _value->_data[index];
}
char& MyString::operator[](int index)
{
//如果_value不是unique,则copy使_value成为unique,在copy上进行修改
if (_value->isShared())
{
//--_value->_refCount; RCPtr会减少引用计数
_value = new StringValue(_value->_data);
}
_value->markUnshareable(); //唯一将共享标识设为false的地方
return _value->_data[index];
}
#endif // 0
//MyString::CharProxy实现
MyString::CharProxy::CharProxy(MyString& str, int index)
:_theString(str), _charIndex(index) {}
MyString::CharProxy& MyString::CharProxy::operator=(const CharProxy &rhs)
{
if (_theString._value->isShared())
_theString._value = new StringValue(_theString._value->_data);
_theString._value->_data[_charIndex] =
rhs._theString._value->_data[_charIndex];
return *this;
}
MyString::CharProxy& MyString::CharProxy::operator=(char c)
{
if (_theString._value->isShared())
_theString._value = new StringValue(_theString._value->_data);
_theString._value->_data[_charIndex] = c;
return *this;
}
MyString::CharProxy::operator char() const
{
return _theString._value->_data[_charIndex];
}
const MyString::CharProxy MyString::operator[](int index) const
{
return CharProxy(const_cast<MyString&>(*this), index);
}
MyString::CharProxy MyString::operator[](int index)
{
return CharProxy(*this, index);
}
void testCharProxy()
{
MyString s1, s2;
cout << s1[5];
s2[5] = 'x';
s1[3] = s2[8];
}
局限性