您的位置:首页 > 其它

string类之深拷贝的两种写法

2016-06-06 22:48 337 查看
1 第一种就是普通写法,需要强调的地方不多,代码中有关地方已经给出注释

/*#include<iostream>
using namespace std;
#
class String
{
public:
//这是系统默认的
String()//这是先给pstr开辟一个空间来存放'\0',注意'\0'的写法
:p(new char[1])
{
*p = '\0';\
}
//显示的给出 开辟空间时候加1是为了放'\0'
//也可以合起来写   改成String(char*p="")
String(char *pstr)
:p(new char[strlen(pstr)+1])
{
if (pstr == NULL)
{
p = new char[1];
*p = '\0';
}
else
{
p = new char[strlen(pstr) + 1];
strcpy(p, pstr);
}
}
拷贝构造函数
String(const String &s)
{
p = new char[strlen(s.p) + 1];
strcpy(p, s.p);
}
//赋值运算符重载
//注意四个问题
//1)返回值
//2)参数
//3)检测其是否给自身赋值
//4)返回为*this
String & operator = (const String &s)
{
if (this != &s)
{
char *tmp = new char[strlen(s.p) + 1];
strcpy(tmp, s.p);
delete []p;
p = tmp;
}
return *this;
}
//析构函数
~String()
{
if (p)
{
delete[] p;
}
}

private:
char *p;
};

int main()
{
String s1;
String s2("aaa");
String s = s2;
String s3(s2);
s2 = s1;

return 0;
}*/


2 简洁版的深拷贝 这是重点要掌握的

在这个版本中,构造函数和析构函数并没有改变,改变的是复制运算符重载,拷贝构造

先看这段实现代码

String(const String &s)

{
String tmp(s.p);
std::swap(p, tmp.p);
}
//赋值运算符重载
/*String &operator=( String s)
{
std::swap(p, s.p);
return *this;
}*/
//另一种写法
String & operator=(const String &s)
{
if ( this != &s)
{
String tmp(s.p);
std::swap(p, tmp.p);
}
return *this;
}


看起来这段代码并没有问题,但是运行起来会崩溃

仔细分析一下是因为p没有具体的指向,但是我们却用它和另一个指针交换所指向的内容,我们使用的这个p此时是野指针.

因此在初始化列表里应该将他置空,此时再来交换就没有问题了

这就是深拷贝的简洁版,直接交换俩个指针的指向,易于理解且写起来不易出错
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: