您现在所在的位置: 北风技术专栏 > Java > 不好驯服的析构函数

不好驯服的析构函数

作者:风风 发布于:2010年06月14日 19:41

首先看一个深拷贝的例子
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

( 内容完 )

添加收藏到:

您可能还对这些文章感兴趣:

  • 向用户、竞争对手学习,是360的微创新之源
  • Asp.net的IP地址屏蔽功能设计
  • j2me 读取多编码格式外部文本文件
  • 如何编出健壮的代码 java编程30条规则
  • 使用RPM包管理命令的笔记
  • 使用Apache mod_evasive防DDOS攻击
  • 说说程序员与博客
  • 关于Java缺乏多继承机制的探讨
  • 用Flex+Lucene+s2sh开发订餐系统开发第三步:前台主界面设计(续)笔记分享
  • 浅谈一个新手如何成为一名C++程序员
  • 没有评论, 我来评论

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

    

    每周之星

    陈臣陈臣

    七年Java和JEE开发经验,JEE应用设计和高级架构师,拥有Sun的多项Java和J2EE方面的技能认证,多年项目经理、技术部经理的管理经验。拥有全面、扎实的Java和JEE理论知识,丰富的JEE应用开发经验。

    更多作者:

  • Adam
  • ikon999
  • jk1234
  • jk2345
  • libin_8745
  • lifengxing
  • taohuang100
  • xingkong
  • 北风
  • 呆子
  • 子晨
  • 小白
  • 张章
  • 张维亮
  • 陈臣
  • 陶宝哥
  • 风风
  • 最新内容

    推荐内容

    标签

    分类