浅拷贝也称值拷贝,在进行赋值时增加了一个指针,且该指针与原指针指向了同一内存空间,那释放这一空间,会导致其他对象所使用的空间也被释放,即程序会调用两次析构函数,同一块空间会被析构两次,结果是程序会出错、崩溃。
代码如下:
#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
using namespace std;
//String类基本包括构造函数、析构函数、拷贝构造函数、运算符重载函数
class String{
//构造函数
public:
String(char* str = "")
:_str(new char[strlen(str) + 1]){
strcpy(_str, str);
}
~String() //析构函数
{
if (_str)
delete[]_str;
}
String(const String& s) //拷贝构造
:_str(new char[strlen(s._str) + 1]){
strcpy(s._str, _str);
}
String& operator=(const String& s){ //operator重载
if (this != &s){ //防止自己给自己赋值
delete[]_str;
char* tmp = new char[strlen(s._str) + 1];//开辟新空间
strcpy(tmp, s._str);
}
return *this;
}
private:
char* _str;
char* getstr(){
return _str;
}
};
深拷贝是不仅增加了一个指针,且重新开辟了一块空间,让指针指向这块空间存储,避免了浅拷贝中会出现的问题。
深拷贝的写法有两种:传统写法和现代写法
传统写法的可读性较高,代码如下:
class String{
private:
char* _str;
public:
//构造函数
String(char* str = "")
: _str(new char(strlen(str) + 1)){
strcpy(_str, str);
}
//析构函数
~String(){
delete(_str);
}
char* getstr(){
return _str;
}
//拷贝构造函数
String(const String& s)
:_str(new char(strlen(s._str) + 1)){
strcpy(_str, s._str);
}
//赋值运算符重载函数
String& operator=(const String& s){
if (this != &s){
delete[]_str;
char* tmp = new char(strlen(s._str) + 1);
strcpy(tmp, s._str);
//_str = tmp;
}
return *this;
}
};
现代写法的代码则相对简洁一些:
class String{
//构造函数
private:
char* _str;
public:
String(char* str = "")
:_str(new char[strlen(str) + 1]){
strcpy(_str, str);
}
~String() //析构函数
{
if (_str)
delete[]_str;
}
char* getstr(){
return _str;
}
String(const String& s)//拷贝构造,
:_str(NULL){
String tmp=s._str;
swap(tmp._str, _str);
}
String& operator=(const String& s){ //赋值重载
if (this != &s){
String tmp=s._str;
swap(tmp._str,_str);
}
return *this;
}
};