C++笔记 30:代理类

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

局限性

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

总结

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值