为什么要引入引用计数写时拷贝?
使用浅拷贝不浪费内存空间却容易发生内存泄漏问题,使用深拷贝不会发生内存泄漏但是会不断开辟新的空间,内存利用率低。
因此结合深浅拷贝的优点产生了写时拷贝。
在String类中添加新成员变量_pcount来计算指向同一段内存空间的指针的数目,若果要修改成员变量,当指针数目为小于等于1时就可以释放空间,大于1则另开辟空间来保存新的数据。
代码如下:
#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
class String{
public:
String(const char* str=""){
_str=new char[strlen(str)+1];
strcpy(_str,str);
_pcount=new int(1);
}
String(const String& s){
_str=s._str;
_pcount=s._pcount;
++(*_pcount);
}
//不能直接释放_str,因为_str指向的空间的指针不止一个
String& operator=(const String& s){
if(_str!=s._str) {
if(--(*_pcount)==0){
delete[] _str;
delete _pcount;
}
_str=s._str;
_pcount=s._pcount;
++(*_pcount);
}
return *this;
}
//修改某一变量的值
//先开辟新的空间,拷贝,修改
//对某一变量进行修改不会影响其他变量的数据
void CopyOnWrite(){
if(*_pcount>1){
char* tmp=new char[strlen(_str)+1];
strcpy(tmp,_str);
--(*_pcount);
_str=tmp;
_pcount=new int(1);
}
}
char& operator[](size_t pos){//是一个可读可写的接口
CopyOnWrite();
return _str[pos];
}
char* c_str(){
return _str;
}
~String(){
if(--(*_pcount)){
delete[] _str;
delete[] _pcount;
}
}
private:
char* _str;
int* _pcount;
};
void Test(){
String s1("hello");
String s2(s1);
s1[0]='x';
cout<<s1.c_str()<<endl;
cout<<s2.c_str()<<endl;
}
int main(){
Test();
}