不好驯服的析构函数
首先看一个深拷贝的例子
view plaincopy to clipboardprint?
#include
using namespace std;
const int SIZE = 9;
const int DEFAULT_NUM = 6;
class A
{
private:
int *p;
int size;
public:
A(A&);
A();
~A();
void set(); //设置A的各个元素的值
void showEle(); //输出p的各个元素
void showAdd(); //输出p的地址
int *getP();
int getSize();
};
A::A()
{
p = NULL;
size = 0;
}
A::~A()
{
delete []p;
p = NULL;
size = 0;
}
A::A(A &right)
{
size = right.getSize();
p = new int[size];
memcpy(p,right.getP(), sizeof(int)*size);
}
void A::set()//设置A的各个元素的值
{
p = new int[SIZE];
size = SIZE;
for(int n=0; n<size; n++)
{
p[n] = DEFAULT_NUM;
}
}
void A::showEle()
{
for(int n=0; n<size; n++)
{
cout<<p[n]<<endl;
}
}
void A::showAdd()
{
cout<<p<<endl;
}
int *A::getP()
{
return p;
}
int A::getSize()
{
return size;
}
int main()
{
A a;
a.set();
a.showEle();
a.showAdd();
A b(a);
b.showEle();
b.showAdd();
return 0;
}
#include
using namespace std;
const int SIZE = 9;
const int DEFAULT_NUM = 6;
class A
{
private:
int *p;
int size;
public:
A(A&);
A();
~A();
void set(); //设置A的各个元素的值
void showEle(); //输出p的各个元素
void showAdd(); //输出p的地址
int *getP();
int getSize();
};
A::A()
{
p = NULL;
size = 0;
}
A::~A()
{
delete []p;
p = NULL;
size = 0;
}
A::A(A &right)
{
size = right.getSize();
p = new int[size];
memcpy(p,right.getP(), sizeof(int)*size);
}
void A::set()//设置A的各个元素的值
{
p = new int[SIZE];
size = SIZE;
for(int n=0; n<size; n++)
{
p[n] = DEFAULT_NUM;
}
}
void A::showEle()
{
for(int n=0; n<size; n++)
{
cout<<p[n]<<endl;
}
}
void A::showAdd()
{
cout<<p<<endl;
}
int *A::getP()
{
return p;
}
int A::getSize()
{
return size;
}
int main()
{
A a;
a.set();
a.showEle();
a.showAdd();
A b(a);
b.showEle();
b.showAdd();
return 0;
} 可能我写的有点乱,成员变量包括一个指针,其实是一个数组,想要深拷贝。
所以我们需要重载拷贝构造函数。
初学C++的时候,直接记住了参数是引用类型,当时对语言没有深入的理解(虽然现在也不深入),也就没有往心里去,这些天模拟STL,遇到了好多关于深拷贝的问题,而且这问题出的很怪异(我会在下午提出),因此想到了拷贝构造函数,所以在这里需要深究一下。
拷贝构造函数的参数是引用类型。
我们可以试想一下不是引用的情况,也就是说,拷贝构造函数是下边这个样子:
view plaincopy to clipboardprint?
A::A(A right)
{
size = right.getSize();
p = new int[size];
memcpy(p,right.getP(), sizeof(int)*size);
}
A::A(A right)
{
size = right.getSize();
p = new int[size];
memcpy(p,right.getP(), sizeof(int)*size);
} 参数传递的是一个对象,按值传递,那么这个对象就会被复制到right,复制的时候又会调用拷贝构造函数,那又会复制一个对象到第二次调用的这个拷贝构造函数里边,因此又需要第三次调用拷贝构造函数。。。想一下,是不是无限循环?
简单地说:传值需要调用拷贝构造函数,而不是引用类型的拷贝构造函数又需要调用拷贝构造函数。因此无限循环。
Ok,把引用的这个问题说明白,下边说一下我这几天遇到的这个问题:
请先看一段代码:
view plaincopy to clipboardprint?
#include
#include
using namespace std;
class A
{
private:
int *p;
int size;
public:
void setSize(int);
void setP(int*);
int getSize() const;
int *getP() const;
void fun(); //设置相应的值,为拷贝做准备
void show();
~A(); //析构函数
A();
A operator = (A right) //重载的等号
{
int *rightP = right.getP();
size = right.getSize();
p = new int[size];
memcpy(p, rightP, size*sizeof(int));
return *this;
}
;
};
void A::setSize(int newSize)
{
size = newSize;
}
void A::setP(int *newP)
{
p = newP;
}
void A::show()
{
for(int n=0;n<size;n++)
{
cout<<p[n]<<endl;
}
}
int *A::getP() const
{
return p;
}
int A::getSize() const
{
return size;
}
A::A()
{
p = NULL;
size = 0;
}
void A::fun()
{
p = new int [9];
for(int n=0;n<9;n++)
{
p[n] = n+1;
}
size = 9;
}
//关键是下边的析构函数,如果进行delete操作,该程序就会出错
A::~A()
{
delete []p;
p = NULL;
size = 0;
}
int main()
{
A a;
a.fun();
cout<<”a.show():”<<endl;
a.show();
A b;
b = a;
cout<<”b.show()”<<endl;
b.show();
cout<<”a.show()”<<endl;
a.show();
return 0;
}
作者:风风
来源:北风技术专栏
原文链接:http://column.ibeifeng.com/allg0/20100614340.shtml
( 内容完 )
添加收藏到:
您可能还对这些文章感兴趣:



没有评论, 我来评论
小贴士:评论需要管理员审核后才会显示。请不要发布与国家法律相抵触的言论,北风网将保留追究责任的权利。
类似“顶”、“沙发”、“支持”之类没有营养的文字,对勤劳贡献的作者来说是令人沮丧的反馈信息。
请勿到处挖坑绊人、招贴广告。既占空间让人厌烦,又没人会搭理,于人于己都无利。
如果您发现自己的评论没有被审核或者不见了,请参考以上三条。