写时拷贝的方式实现C++中string类

来源:互联网 发布:windows微信登录 编辑:程序博客网 时间:2024/06/05 07:03

一、写时拷贝的引入

class String{friend ostream& operator<<(ostream& os,const String& s);public:String(const char* s):_str(new char[strlen(s)+1]){strcpy(_str,s);}//深拷贝String(String& s)//拷贝构造:_str(new char[strlen(s)+1]){strcpy(_str,s._str);}private:char* _str;};
void test1(){String str1("abcde");String str2(str1);cout<<str1<<endl;cout<<str2<<endl;}

这个String类中只简单实现了构造函数和拷贝构造函数,很明显可以看出,在创建str1和str2时都开辟了空间。但是对于str2,只是单纯的使用了它并将str2所指向的内容输出,并没有操作这块空间,因此给str2开辟空间会显得有点浪费。这时就可以引用写时拷贝的方式。

二、什么是写时拷贝?

顾名思义,写时拷贝就是在需要修改这块空间的内容时才分配一块空间。同样用上边的例子,写时拷贝会存在一个计数器,并且多个对象指向同一块空间,每次创建一个新的对象时,计数器++,销毁时计数器 - - (具体代码如下:)


实现一:

//计数器class String{friend ostream& operator<<(ostream& os,const String& s);public:String(const char* s = ""):_str(new char[strlen(s)+1]),_pCount(new int(1)){cout<<"gouzao"<<endl;strcpy(_str,s);}String(String& s)//拷贝构造:_str(s._str),_pCount(s._pCount){cout<<"kaobeigouzao"<<endl;++ *_pCount;}~String(){if(--_pCount[0] == 0){cout<<"~String()"<<endl;delete[] _str;delete _pCount;}}String& operator = (const String& s){_str = s._str;_pCount = s._pCount;if (this != &s)//检测是否自赋值{if(--*_pCount == 0){delete[] _str;_str = new char[strlen(s._str)+1];strcpy(_str,s._str);}}return *this;}private:char* _str;int* _pCount;};ostream& operator<<(ostream& os,const String& s){os<<s._str<<endl;return os;}
void test(){String str1("abcde");String str2(str1);String str3;str3 = str2;cout<<str1<<endl;cout<<str2<<endl;cout<<str3<<endl;}
实现二:

将_pCount与_str所指向的空间放在一起,即只用new开辟一次空间


class String{friend ostream& operator<<(ostream& os,String& s);public:String(const char*str = ""):_str(new char[strlen(str)+1+4]){*(int *)_str = 1;//*_pCount = 1_str = _str+4;//找到数据存放的位置strcpy(_str,str);GetCount() = 1;}String(const String& str):_str(str._str){++GetCount();}~String(){if(--GetCount() == 0){delete[] (_str-4);}}String& operator=(const String& s){if (this != &s){if (--GetCount() == 0){delete[] (_str-4);  }++GetCount();_str = s._str;}return *this;}private:int& GetCount()//获得_pCount{return *((int *)_str-1);}private:char *_str;};ostream& operator<<(ostream& os,String& s){os<<s._str;return os;}
void test1(){String str1("abcde");String str2(str1);String str3;str3 = str2;cout<<str1<<endl;cout<<str2<<endl;cout<<str3<<endl;}


1 1
原创粉丝点击