关闭

不知不觉中调用的默认拷贝构造函数

2531人阅读 评论(6) 收藏 举报

        大家都知道在一个对象的赋值过程中就会调用默认的拷贝
构造函数(如果你没有明确定义这部分代码的情况下),这
时在你的类的设计过程中有一个指针成员变量,这时可能就
可能潜在一定的危险在里边。在这里举个例子来说明以下:
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;
}

   进行上述修改后,我们就可以尽情地使用该类。在赋值时,
也不会出现意想不到的情况。

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:437552次
    • 积分:6357
    • 等级:
    • 排名:第3985名
    • 原创:188篇
    • 转载:29篇
    • 译文:1篇
    • 评论:68条
    最新评论