引用计数是这样一个技巧,它允许多个有相同值的对象共享这个值的实现。引用计数是个简单的垃圾回收体系。
l 实现引用计数
class String {
public:
... // the usual String member functions go here
private:
struct StringValue { ... }; // holds a reference count and a string value
StringValue *value; // value of this String
};
这是StringValue的实现:
class String {
private:
struct StringValue {
int refCount;
char *data;
StringValue(const char *initValue);
~StringValue();
};
...
};
String::StringValue::StringValue(const char *initValue): refCount(1)
{ data = new char[strlen(initValue) + 1];
strcpy(data, initValue);}
String::StringValue::~StringValue()
{ delete [] data;}
StringValue的主要目的是提供一个空间将一个特别的值和共享此值的对象的数目联系起来。
String构造函数:
String::String(const char *initValue)
: value(new StringValue(initValue))
{}
String::String(const String& rhs)
: value(rhs.value)
{
++value->refCount;
}
String析构函数:
String::~String()
{
if (--value->refCount == 0) delete value;
}
赋值操作:
String& String::operator=(const String& rhs)
{
if (value == rhs.value) { // do nothing if the values
return *this; // are already the same; this
} // subsumes the usual test of
// this against &rhs (see Item E17)
if (--value->refCount == 0) { // destroy *this's value if
delete value; // no one else is using it
}
value = rhs.value; // have *this share rhs's
++value->refCount; // value
return *this;
}
l 写时拷贝
char& String::operator[](int index)
{
// if we're sharing a value with other String objects,
// break off a separate copy of the value for ourselves
if (value->refCount > 1) {
--value->refCount; // decrement current value's
// refCount, because we won't
// be using that value any more
value = // make a copy of the
new StringValue(value->data); // value for ourselves
}
// return a reference to a character inside our
// unshared StringValue object
return value->data[index];
}
这个“与其它对象共享一个值直到写操作时才拥有自己的拷贝”的想法在计算机科学中已经有了悠久而著名的历史了,尤其是在操作系统中:进程共享内存页直到它们想在自己的页拷贝中修改数据为止。这个技巧如此常用,以至于有一个名字:写时拷贝。它是提高效率的一个更通用方法--Lazy原则--的特例。
原文讨论的其它问题,略。