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

// Reference-counting pointer
template<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 object
class 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 class
class 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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值