大家都知道在一个对象的赋值过程中就会调用默认的拷贝
构造函数(如果你没有明确定义这部分代码的情况下),这
时在你的类的设计过程中有一个指针成员变量,这时可能就
可能潜在一定的危险在里边。在这里举个例子来说明以下:
class test
{
public:
test(void) { nIndex = new int; }
~test(void) { delete nIndex; nIndex = NULL; }
private:
int *nIndex;
};
有的时候我们可能会这样设计自己的代码,在构造函数内
分配内存,在析构函数中释放内存,看似没有什么问题,但
是在这个程序中潜在着危险。试想一下,我们这样来使用这
个类:
test test1;
test test2 = test1;
test test3;
test3 = test2;
在这里,test的构造函数被调用了两次(test1和test3),
而析构函数却被调用了3次,test1,test2,test3各一次。
由于赋值的默认解释是按成员赋值,所以在程序结束的时
候,test1,test2,test3中各包含一个指针,他们都指向
test1构造时分配的那块内存。在test3建立时分配的内存的
指针没有被保留下来,被赋值语句覆盖掉了(test3 = test2;),
这样这块内存就永远丢掉了,也就出现了内存泄露。上面的3次
析构,预示着相同的内存要释放3次,这种情况导致的结果是很
糟糕的。
知道上面的问题,以及问题的所在,我们就可以对它进行修
正,是程序按我们自己的方式去执行。既然是默认拷贝构造出的
问题,那我们就把它定义清楚:
class test
{
public:
test(void) { nIndex = new int; }
~test(void) { delete nIndex; nIndex = NULL; }
test(const test &t);
test& operator=(const test &t);
private:
int *nIndex;
};
inline test::test(const test &t)
{
nIndex = new int;
*nIndex = *(t.nIndex);
}
inline test& test::operator=(const test &t)
{
if (this != &t)
{
delete nIndex;
nIndex = new int;
*nIndex = *(t.nIndex);
}
return *this;
}
进行上述修改后,我们就可以尽情地使用该类。在赋值时,
也不会出现意想不到的情况。
本文通过实例深入探讨了在C++中,如果类的设计不当如何导致内存泄漏及重复释放的问题,并提供了正确的拷贝构造函数和赋值运算符重载实现。

1720

被折叠的 条评论
为什么被折叠?



