string类的浅拷贝,深拷贝,写实拷贝

来源:互联网 发布:淘宝服装店如何推广 编辑:程序博客网 时间:2024/06/11 16:10

string类的浅拷贝形式,这种情况下程序会奔溃,因为拷贝构造时共用了一块空间,但会析构两次,第一次释放后就为空

#include <iostream>#include <string.h>using namespace std;class String{public:String (const char*  str = ""){     if (str == NULL)     {    _str = new char[1];    _str = '\0';      }     else{ _str=new char [strlen(str) +1];strcpy(_str, str);}}String (const String& s ){strcpy(_str,s._str);} String&  String:: operator =(const String&  s){if (_str != s._str){strcpy(_str,s._str);}return (*this);}String::~String(){if ( _str != NULL){   delete[] _str;_str = NULL;}}private:char* _str;};
深拷贝第一种形式
#include <iostream>#include <string.h>using namespace std;//  深拷贝简单版本class String{public:String(const char* str = "" ){if (NULL == str){_str = new char [1];_str = '\0';         }else {_str = new char[strlen(str)+1] ;strcpy(_str,str);}}String (const String& s):_str(new char[strlen(s._str)+1] ){if (this != &s){strcpy (_str, s._str) ;}}String& operator = (const String &s){String temp(s);return temp;}~String (){if (NULL != _str){delete [] _str;cout << "~String()"<<endl;          _str = NULL;}}private:char* _str;};

第二种形式:

#include <iostream>#include <string.h>class String{public :String(const char* str = "" ){if (NULL == str){_str = new char [1];_str = '\0';         }else {_str = new char[strlen(str)+1] ;strcpy(_str,str);}}String (const String& s):_str(NULL){String temp(s._str);std::swap (_str , temp._str);}String& operator = (const String& s){String temp(s);return temp;}~String (){if (NULL != _str){delete [] _str;std::cout << "~String()"<<std::endl;}}private:char *_str;};

上面两种形式不会出现问题,但是相同的字符串会开辟两个空间,有一定的浪费

写实拷贝引用计数int *:这种情况会造成string类的长度不一致,造成内存碎片

#include <iostream>#include <string.h>using namespace std;class String {public :      String (const char* str = "")  : _refcount (new int [1])  {         if ( NULL == str) { _str = new char [1]; _str = '\0'; } else  { _str  = new char [strlen (str)+1]; strcpy (_str, str);    (*_refcount) = 1;}  }  String (const String&s)  :_str(s._str)  ,_refcount(s._refcount)  {  (*_refcount) ++;  }          String& operator = (const String& s )  {  if (this != &s)  {         String temp(*this);     _str = s._str;     _refcount = s._refcount;     (*_refcount) ++; if( -- (*temp._refcount) == 0) { delete [] temp._str; delete [] temp._refcount; } (*_refcount ) ++;  }  return (*this);  }  ~String ()  {  if ( --(*_refcount) == 0 && _str!= NULL)  {  delete [] _str;  delete []_refcount;  _str = NULL;  cout<<"~String ()"<< endl;  }  }private:  char *_str;      int*  _refcount;};


写实拷贝:

#include <iostream>#include <string.h>using namespace std;class String {public :String (const char* str = ""):_str(new char [strlen(str)+5]){if (NULL == str){_str = new char(5);*(int*)_str= 1;_str += 4;_str = '\0';}else {     *(int*)_str= 1;     _str += 4; strcpy (_str, str);} }String (const String& s):_str(s._str){(*(int*)(_str-4)) ++;}String operator = (const String& s){if (_str != s._str){            Release();_str = s._str;(*(int*)(_str-4)) ++;}return (*this);}~String (){if ( -- (*(int*)(_str-4)) == 0 ){delete [] (_str-4 );_str = NULL;cout <<"~String ()"<<endl;}}void Release (){if ( --(*(int*)(_str-4)) == 0){delete [](_str-4);}}friend ostream& operator<<(ostream& cout, String& s){cout << s._str << endl;return cout;}char operator[] (const int index){return _str[index];}private:char* _str;};


2 0