引自:http://www.programlife.net/copy-on-write.html
Copy On Write(写时复制)是在编程中比较常见的一个技术,面试中也会偶尔出现(好像Java中就经常有字符串写时复制的笔试题),今天在看《More Effective C++》的引用计数时就讲到了Copy On Write——写时复制。下面简单介绍下Copy On Write(写时复制),我们假设STL中的string支持写时复制(只是假设,具体未经考证,这里以Mircosoft Visual Studio 6.0为例,如果有兴趣,可以自己翻阅源码)
Copy On Write(写时复制)的原理是什么?
有一定经验的程序员应该都知道Copy On Write(写时复制)使用了“引用计数”,会有一个变量用于保存引用的数量。当第一个类构造时,string的构造函数会根据传入的参数从堆上分配内存,当有其它类需要这块内存时,这个计数为自动累加,当有类析构时,这个计数会减一,直到最后一个类析构时,此时的引用计数为1或是0,此时,程序才会真正的Free这块从堆上分配的内存。
引用计数就是string类中写时才拷贝的原理!
什么情况下触发Copy On Write(写时复制)
很显然,当然是在共享同一块内存的类发生内容改变时,才会发生Copy On Write(写时复制)。比如string类的[]、=、+=、+等,还有一些string类中诸如insert、replace、append等成员函数等,包括类的析构时。
代码如下:
#include <iostream>
#include <string>
using namespace std;
int main(int argc, char **arg)
{
string sa = "Copy on write";
string sb = sa;
string sc = sb;
cout<<&sa<<endl;
printf("sa char buffer address: 0x%08X\n", sa.c_str());
printf("sb char buffer address: 0x%08X\n", sb.c_str());
printf("sc char buffer address: 0x%08X\n", sc.c_str());
sc = "Now writing...";
printf("After writing sc:\n");
printf("sa char buffer address: 0x%08X\n", sa.c_str());
printf("sb char buffer address: 0x%08X\n", sb.c_str());
printf("sc char buffer address: 0x%08X\n", sc.c_str());
return 0;
}
运行结果
sa char buffer address: 0x00380911
sb char buffer address: 0x00380911
sc char buffer address: 0x00380911
After writing sc:
sa char buffer address: 0x00380911
sb char buffer address: 0x00380911
sc char buffer address: 0x00380969
Press any key to continue
可以看到,VC6里面的string是支持写时复制的。
写时复制的核心思想是将需要做的事情推迟到事情即将发生的时刻做,实现“写时复制”的核心方法是“引用计数”,这是实现写时复制的关键。