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

时间:2021-04-06 19:51:23

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;
};