1.浅拷贝:

//浅拷贝
class String
{
public:
String(const char* str)
: _str(new char[strlen(str) + 1])
{
strcpy(_str, str);
}
//拷贝构造
String(const String& str)//浅拷贝--s1和s2同时会指向同一块空间。
: _str(str._str)
{}

String& operator =(const String& str)
{
if (this != &str)
{
_str = str._str;
}
return *this;
}

~String()
{
if (_str)
{
delete[] _str;
}
}
private:
char* _str;
};

void TestString()
{
String s1("hello world!");
String s2 = s1;//s1和s2同时指向同一块空间,析构时会析构两次,崩溃
}

C++String深浅拷贝问题_赋值

2.深拷贝

//传统写法
class String
{
public:
//String()
//:_str(new char[1])
//{
// _str[0] = '\0';
//}

//带缺省参数更好
String(char* str= "")
:_str(new char[strlen(str) + 1])
{
strcpy(_str, str);
}
String(const String& s)
:_str(new char[strlen(s._str) + 1])
{
strcpy(_str, s._str);//复制
}
String& operator=(const String&s)
{
if (this != &s) //自己不能给自己赋值
{
char* tmp = new char[strlen(s._str) + 1];
strcpy(tmp, s._str); //把_str复制给tmp
delete[] _str; //[] 删除原来的_str
_str = tmp; //再把tmp赋值给新的_str 实现上面的功能

}
return *this;
}

~String()
{
if (_str)//如果不为空,delete
{
delete[] _str;
cout << "~String" << endl;
}
}
private:
char* _str;
};

void TestString1()
{
String s1("wwwwwwwww");
String s2(s1);
String s3;
s3 = s1;
}


现代写法:

class String
{
public:
String(char* str = "")//带有缺省参数的构造函数
:_str(new char[strlen(str) + 1])//开辟strlen(str)+1个空间
{
strcpy(_str, str);//String类的用strcpy进行拷贝即可
}

String(const String& s)//拷贝构造
:_str(NULL)
{
String tmp(s._str);//先用s构造个临时对象tmp
swap(_str, tmp._str);//然后进行交换,这样_str就指向了拷贝构造的内容
//tmp过了作用域后就自动被析构
}

String& operator=(String s)//注意没有&,现代写法这里可以创建临时对象
{
swap(_str, s._str);//直接swap,
return *this;
}

~String()
{
if (_str)
{
delete[] _str;
//cout << "~String()" << endl;
}
}

private:
char* _str;
};

void TestString2()
{
String s1("xxxxx");
String s2(s1);
String s3;
s3 = s1;
}

C++String深浅拷贝问题_拷贝构造_02