当类里面有指针对象时,由于浅拷贝是由两个对象指向同一块内存,存在崩溃的问题!为了解决,所以引入了深拷贝、写时拷贝。
1.浅拷贝(新开辟一个指针做引用计数)
//浅拷贝+引用计数(指针)
class String
{
public:
String(char* str="")//缺省时给定\0
:_str(new char[strlen(str)+1])
,_pCount(new int(1))
{
strcpy(_str,str);
*_pCount=1;
}
String(String & s)
:_str(s._str)
,_pCount(s._pCount)
{
(*_pCount)++;
}
String& operator=(const String& s)
{
if(this!=&s)
{
this->_Release();
_str=s._str;
_pCount=s._pCount;
(*_pCount)++;
}
return *this;
}
~String()
{
_Release();
}
void Print()
{
printf("%s %d\n",_str,*_pCount);
}
protected:
char* _str;
int* _pCount;
void _Release()
{
if(--(*_pCount)==0)
{
delete [] _str;
delete _pCount;
}
}
};
int main()
{
String s("hello");
s.Print();
String s1(s);
s1.Print();
String s2=s;
s2.Print();
system("pause");
return 0;
}
2.浅拷贝(在原有的字符串中留int数据大小存计数器)
//浅拷贝+引用计数(_str前给一个int数据大小存计数器)
class String
{
public:
String(char* str="")
:_str(new char[strlen(str)+5])
{
_str+=4;
strcpy(_str,str);
_GetCount(_str)=1;
}
String(const String& s)
//:_str(new char[strlen(s._str)+5])//拷贝构造不也是构造吗,为什么不用开辟空间。浅拷贝指向同一块空间,不用开辟
// :_str(s._str)
{
_str+=4;
_str=s._str;
_GetCount(_str)+=1;
}
String& operator=(const String& s)
{
if(this!=&s)
{
this->_Release();
_str+=4;
_str=s._str;
_GetCount(_str)+=1;
}
return *this;
}
~String()
{
_Release();
}
void Print()
{
printf("%s %d\n",_str,_GetCount(_str));
}
protected:
char* _str;
int Count;
void _Release()
{
if(--_GetCount(_str)==0)
{
delete [] (_str-4);
}
}
int& _GetCount(char* str)
{
return *((int*)str-1);
}
};
int main()
{
String s("hello");
s.Print();
String s1(s);
s1.Print();
String s2=s;
s2.Print();
system("pause");
return 0;
}
3.深拷贝
//深拷贝
class String
{
public:
String(char* str="")
:_str(new char[strlen(str)+1])
{
strcpy(_str,str);
}
String(const String& s)
//:_str(new char[strlen(s._str)+1])///这个方法有木有错
:_str(NULL)
{
//strcpy(_str,s._str);
String tmp(s._str);
swap(_str,tmp._str);
}
String& operator=(const String& s)
{
//strcpy(_str,s._str);为什么不可以。2个指针指向同一块空间。1)释放2次。2)一动两变。3)_str原有内存没有释放
String tmp(s._str);
swap(_str,tmp._str);
return *this;
}
~String()
{
delete [] _str;
}
void Print()
{
printf("%s\n",_str);
}
protected:
char* _str;
};
int main()
{
String s("hello");
s.Print();
String s1(s);
s1.Print();
String s2=s;
s2.Print();
system("pause");
return 0;
}
转载于:https://blog.51cto.com/10707460/1754867