1. 什么是写时拷贝
写时拷贝故名思意:是在写的时候(即改变字符串的时候)才会真正的开辟空间拷贝(深拷贝),如果只是对数据的读时,只会对数据进行浅拷贝。
写时拷贝:引用计数器的浅拷贝,又称延时拷贝
:写时拷贝技术是通过"引用计数"实现的,在分配空间的时候多分配4个字节,用来记录有多少个指针指向块空间,当有新的指针指向这块空间时,引用计数加一,当要释放这块空间时,引用计数减一(假装释放),直到引用计数减为0时才真的释放掉这块空间。当有的指针要改变这块空间的值时,再为这个指针分配自己的空间(注意这时引用计数的变化,旧的空间的引用计数减一,新分配的空间引用计数加一)。
2. string中的两种写时拷贝
一:
- 动态开辟两个空间一个用来存放字符串:_str,一个用来存放计数器_refCountPtr
- 每次拷贝构造时(赋值运算符的重载后半段),直接把字符串的指针付给新的String,然后给计数器加加(*_refCountPtr)++
- 在释放String的时候,先对计数器减减,再判断计数器是否为零(即看是否还有指针共享此内存),若计数器为零则直接释放_str 和 _refCountPtr
- 在对字符串进行更改的时候(写时),就要进行深拷贝:先进行步骤3,在进行深拷贝和字符串的更改
class String//写时拷贝
{
public:
String(char * str = "\0")
:_refCountPtr(new int(1))//开辟计数器动态内存
,_size(strlen(str))
{
_capacity = _size;
_str = new char[_capacity+1];//开辟字符串动态内存
strcpy(_str,str);
}
String(String& s)//拷贝构造
:_str(s._str)//直接浅拷贝
,_refCountPtr(s._refCountPtr)
,_size(s._size)
,_capacity(s._capacity)
{
(*