昨天在工作中遇到一个问题,这样:
while(...)
{
.....
//昨天在做装备洗练功能的时候,点击洗练按钮整个程序就挂掉了,找了半天,发现是下面这个问题。
//这样赋值后,第一次循环结束释放a没有问题,但是当第二次循环结束再次释放a的时候,整个程序crash掉了。
//原因: 因为A类(A类有父类)不是我写的,A使用了默认拷贝构造函数,导致A类中的指针发生了浅拷贝,然后第一次释放a对象,调用析构函数,delete了其中的指针,
//注意此时delete的是b中指针所指向的内存,然后第二次循环结束时释放a对象,再次delete之前已经释放掉了的指针,导致程序crash.
A a = b;
.....
}
//上述描述可以转换为下面的代码
class A1
{
public:
A1(int temp)
{
p = new int(temp);
}
~A1()
{
//去掉这句话,就不会crash,但是会导致最后一个引用这块内存的对象被释放的时候,p所指向的内存没有对象再可以找到它,也就导致了内存泄漏
delete p;
}
int* p;
};
int _tmain(int argc, _TCHAR* argv[])
{
A1 a(5);
for(int i = 0 ; i < 2;i++)
{
//调用默认拷贝构造函数
A1 b = a;
}
getchar();
}
所以,对于一个类中有指针变量的时候,我们要实现自定义的拷贝构造函数,使用深拷贝,而不是上诉那样的浅拷贝,如下:
class B
{
public:
B(int temp)
{
p = new int(temp);
}
B(B& b)
{
//分配自己的内存,而不是使用b对象中分配的内存
p = new int( *(b.GetData()) );
}
~B()
{
delete p;
}
int* GetData()
{
return p;
}
private:
int* p;
};
int _tmain(int argc, _TCHAR* argv[])
{
B a(5);
for(int i = 0 ; i < 2;i++)
{
B b = a;
}
getchar();
}