引用计数是对共享的动态内存的一种管理方法,STL库的string就是用到了引用计数的方法。本文简单描述引用计数的原理,重点以一个实例来说明怎么在程序中实现引用计数。
1. 概念
引用计数用来记录当前有多少指针指向同一块动态分配的内存。当有指针指向这块内存时,计数器加1;当指向此内存的指针销毁时,计数器减1。当引用计数为0时,表示此块内存没有被任何指针指向,此块被共享的动态内存才能被释放。
2. STL库的string利用引用计数共享内存
如下例:
#include <iostream>
#include <string>
using namespace std;
int main()
{
}
结果如下:
the address of s_1 is: 9042014
the address of s_2 is: 904202c
the address of s_3 is: 9042014
the address of s_4 is: 9042014
the address of s_1 is: 904202c
the address of s_1 is: 9042044
STL string共享内存的原则(copy on write):
利用初始化或赋值生成多个内容相同的string,当没有对这些string进行写操作时,它们会共享同一块内存。当有写操作出现时,才会有新的内存重新分配。
3. 利用引用计数实现简易String
问题:我们对String类的内存进行计数,但引用计数这个变量是类的什么类型的成员变量?
解答:
1) 普通私有成员变量,每个类都有一个独立的计数器变量,在新的类对象拷贝构造和赋值的时候需要进入原来的类对象中去获取这个计数器,再进行修改,在同一个类对象之间缺乏通用性。
2) static变量,类的所有对象公用一个计数器变量。字符串”aaaa”和”bbbb”使用不同的内存,它们应该分别有对应自己内存的计数器变量。
3) 结论,对每一块内存分配一个变量,可以在动态分配字符串内存是多分配一个字节,将计数器的值放在第一个字节中;也可以在动态分配内存前先动态分配一个int型的内存来存放这个计数器。
String的代码如下:
#include <iostream>
#include <cstring>
#include <cassert>
class String
{
public:
private:
};
int main()
{
}
String::String(const char *str = NULL)
{
}
String::String(const String& other)
{
}
String& String::operator = (const String& other)
{
}
char& String::operator [] (int index)
{
}
String::~String()
{
}
运行结果如下:
---constructor---
Allocate memory of aaaa at 9509018
The Refcount of aaaa is 1
---constructor---
Allocate memory of bbbb at 9509038
The Refcount of bbbb is 1
---copy constructor---
The Refcount of aaaa is 2
---copy constructor---
The Refcount of aaaa is 3
---assign value---
The Refcount of bbbb is 2
---operator []---
Re-Allocate memory at 9509058
The new Refcount (Re-Allocated) is 1
The Refcount of original String bbbb is 1
---destructor---
The Refcount of aaaa is 1
---destructor---
The Refcount of aaaa is 0
Delete memeory of aaaa at 9509018
---destructor---
The Refcount of bbbb is 0
Delete memeory of bbbb at 9509038
---destructor---
The Refcount of bbab is 0
Delete memeory of bbab at 9509058
转载自:http://blog.sina.com.cn/s/blog_7708265a01010pb5.html