// 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;
}
Effective C++ 一个简单的 String 类的 Reference Counting 实现(C++)
最新推荐文章于 2023-09-19 08:00:00 发布