Proxy class与左值右值运用

Proxy class与左值右值运用
我们修改operator[],令它返回字符串中的字符的proxy,而不返回字符本身。等待最终结果到底是如何运用的。
//1.指定它代表哪一个字符串中的哪一个字符
//2.赋值代表则为那个字符串的左值运用
//3.以其他方式使用之,调用operator[]函数则为右值运用
之后再考虑当有operator=时运用左值运用,其余时候为右值运用。
详细见class CharProxy,它就是返回的proxy class,针对于proxy重载所需要的左右值运用。

template<class T>class RCPtr//智能指针
{
public:
	RCPtr(T* realPtr)
		:pointee(realPtr) {
		init();
	}
	RCPtr(const RCPtr& rhs)
		:pointee(rhs.pointee) {
		init();
	}//拷贝构造函数
	~RCPtr()
	{
		if (pointee)pointee->removeReference();
	}
	RCPtr& operator=(const RCPtr& rhs)
	{
		if (pointee != rhs.pointee)
		{
			if (pointee)
				pointee->removeReference();
			pointee = rhs.pointee;
			init();
		}
		return *this;
	}//赋值构造函数
	T* operator->() const
	{
		return pointee;
	}//指向函数
	T& operator*() const
	{
		return *pointee;
	}//解引用构造函数
private:
	T *pointee;//dump指针
	void init();
};
template<class T>void RCPtr<T>::init()
{
	if (pointee == 0)return;//如果dumb pointer是null,那么smart pointer也是。
	if (pointee->isShareable() == false)
	{
		pointee = new T(*pointee);	//如果其值不可共享,就复制一份
									//调用的是String::StringValue的拷贝构造函数
	}
	pointee->addReference();
}
class RCObject
{
public:
	void addReference()
	{
		++refCount;
	}
	void removeReference()
	{
		if (--refCount == 0)
			delete this;
	}
	void markUnshareable()
	{
		shareable = false;
	}
	bool isShareable() const
	{
		return shareable;
	}
	bool isShared() const
	{
		return refCount>1;
	}
protected:
	RCObject()
		:refCount(0), shareable(true) {};
	RCObject(const RCObject& rhs)
		:refCount(0), shareable(true) {};
	RCObject& operator=(const RCObject& rhs)
	{
		return *this;
	}
	virtual ~RCObject() {};
private:
	int refCount;
	bool shareable;
};

class String
{
public:
	String(const char*value = "");
	//1.指定它代表哪一个字符串中的哪一个字符
	//2.赋值代表则为那个字符串的左值运用
	//3.以其他方式使用之,调用operator[]函数则为右值运用
	class CharProxy
	{
	public:
		CharProxy(String& str, int index)
		:theString(str),charIndex(index){}
		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;
		}
		CharProxy& operator=(char c)
		{
			if (theString.value->isShared())
			{
				theString.value = new StringValue(theString.value->data);
			}
			theString.value->data[charIndex] = c;
			return *this;
		}
		operator char()const//右值运用
		{
			return theString.value->data[charIndex];
		}
	private:
		String& theString;
		int charIndex;
	};
	const CharProxy operator[](int index)const
	{
		return CharProxy(const_cast<String&>(*this), index);//去掉const
	}
	CharProxy operator[](int index)
	{
		return CharProxy(*this, index);
	}
	//只确定是哪个字符串中的哪个字符
	friend class CharProxy;
private:
	struct StringValue :public RCObject
	{
		char *data;
		StringValue(const char *initValue)
		{
			init(initValue);
		}
		StringValue(const StringValue& rhs)
		{
			init(rhs.data);
		}
		void init(const char *initValue)
		{
			data = new char[strlen(initValue) + 1];
			strcpy(data, initValue);
		}
		~StringValue()
		{
			delete[]data;
		}
	};
	RCPtr<StringValue> value;
};

缺陷:
对proxy取址所获得的指针型与对真实对象取址所获的指针型别不同。
CharProxy转换为char是错误的。
注意:编译器在【将调用端自变量转换为对应的被调用端函数参数】过程中,运用【用户定制转换函数】的次数只限于一次。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值