条款11: 为需要动态分配内存的类声明一个拷贝构造函数和一个赋值操作符

条款11: 为需要动态分配内存的类声明一个拷贝构造函数和一个赋值操作符

这是非常重要的一条,经常会导致一些内存的泄露,如以下这段代码所示:
// 一个很简单的string类
class string {
public:
string(const char *value);
~string();

... // 没有拷贝构造函数和operator=

private:
char *data;
};

string::string(const char *value)
{
if (value) {
data = new char[strlen(value) + 1];
strcpy(data, value);
}
else {
data = new char[1];
*data = '\0';
}
}
inline string::~string() { delete [] data; } //还是会产生一个函数的地址
来看看在 没有拷贝构造函数和operator=的情况,
最简单的:
string a("hello");
string b("world");
b=a;
如果没有拷贝构造函数,系统会默认进行一对一的赋支,那么b中的char指针数据就丢失了。

另外一种情况,如果离开了它的生存空间被系统析构
string a("hello"); // 定义并构造 a

{ // 开一个新的生存空间
string b("world"); // 定义并构造 b

...

b = a; // 执行 operator=,
// 丢失b的内存

} // 离开生存空间, 调用
// b的析构函数
string c = a; // c.data 的值不能确定!
// a.data 已被删除
delete c // delete a;

那么不难想到,像这样被系统析构掉的还有一种情况就是传值
void donothing(string localstring) {}
那么这个函数退出时,localstring就被析构,牵连到的还有原来的值

effectiv给出一个比较均衡的方法是可以用比较复杂的计数,来跟踪当前数据结构;或者对一些花费代价

比较大的类里,将拷贝和构造设置成私有的函数

在写法上可以将拷贝和赋值写在一起
比如
string& string::operator=(const string& rhs)
{
//do...
}


string::YourClass(string &str)
{
*this=str;//调用赋值函数
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值