- 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
- 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
第14章 堆与拷贝构造函数
在C++中,堆分配的概念得到了扩展,不仅C++的关键字new和delete可以分配和释放堆空间,而且通过new建立的对象要调用构造函数,通过delete删除对象也要调用析构函数。另外,当对象被传递给函数或者对象从函数返回的时候,会发生对象的拷贝。但有些情况,一模一样的拷贝并不是所希望的,这就要借助于定义拷贝构造函数了。学习本章后,应该掌握new和delete这两个操作符的使用,并能把握从堆中分配和释放对象以及对象数组的时机;领会拷贝构造函数的实质,区别浅拷贝和深拷贝,在程序中适当地运用拷贝构造函数。
14.1 关于堆
C++程序的内存格局通常分为四个区
(1)全局数据区(data area);
(2)代码区(code area);
(3)栈区(stack area);
(4)堆区(即自由存储区)(heap area)。
全局变量、静态数据、常量存放在全局数据区,所有类成员函数和非成员函数代码存放在代码区,为运行函数而分配的局部变量、函数参数、返回数据、返回地址等存放在栈区,余下的空间都被作为堆区。
函数void* malloc(size-t);和void free(void*);在头文件malloc.h中声明,而操作符new和delete是C++语言的一部分,无须包含头文件。它们都从堆中分配和释放内存块,但在具体操作上两者有很大的区别。
操作堆内存时,如果分配了内存,就有责任回收它,否则运行的程序将会造成内存泄漏。这与函数中在栈区分配局部变量有本质的不同。
对C++来说,管理堆区是一件十分复杂的工作,频繁地分配和释放不同大小的堆空间,将会产生堆内碎块。
14.2 需要new和delete的原因
从C+十的立场上看,不能用malloc()函数的一个原因是,它在分配空间的时候不能调用构造函数。类对象的建立是分配空间、构造结构以及初始化的三位一体,它们统一由构造函数来完成。
例如,下面的代码用malloc()分配对象空间:
class Tdate
{
public:
Tdate();
SetDate(int m=1,int d=l,int y=1998);
protected:
int month;
int day;
int year;
};
Tdate::Tdate()
{
month=1;
day=1;
year=l;
}
voidTdate::SetDate(int m,int d, int y)
{
if(m0 m13)
month=m;
if(dO d32)
day=d;
if(y0 y3000)
year=y;
}
void fn()
{
Tdate* pD; //仅仅是个指针,没有产生对象
pD=(Tdate*)malloc(sizeof Tdate); //并不调用构造函数
//...
free(pD); //并不调用析构函数
}
指针pD的声明不为Tdate调用其构造函数,因为pD没有指向任何东西。假如构造函数要被调用,则必须在进行内存分配的ma]loc()调用时进行。然而malloc()仅仅只是一个函数调用,它没有足够的信息来调用一个构造函数,它所接受的参数是一个unsigned long类型。
pD从malloc()那儿获得的不过是一个含有非法数据的类对象空间而已,对应的对象空间中的值不确定。为此,须在内存分配之后再进行初始化。
例如,下面的代码描述用malloc()来进行对象的创建过程:
void fn()
{
Tdate*pD;
pD=(Tdate*)malloc(sizeof Tdate);
pD-SetDate(); //设置Tdate值
//...
free(pD);
}
这从根本上说,不是一个类对象的创建,因为它绕过了构造函数。
另外,从程序设计的需要来看,在分配内存申请的时候,总是知道分配的空间派什么用,而且分配空间大小总是某个数据类型(包括类类型)的整数倍。因而C++用new代替C的malloc()是必然的。
14.3分配堆对象
C++的new和delete机制更简单易懂。例如,下面的代码可与前面的代码做
文档评论(0)