《堆与复制构造函数》PPT课件.ppt
《《堆与复制构造函数》PPT课件.ppt》由会员分享,可在线阅读,更多相关《《堆与复制构造函数》PPT课件.ppt(54页珍藏版)》请在三一办公上搜索。
1、C+面向对象程序设计教学内容,第1章 C+概述第2章 类和对象第3章 面向对象程序设计概述第4章 进一步学习类和对象第5章 堆与复制构造函数第6章 继承性:派生类第7章 运算符重载第8章 虚函数和多态性第9章 模板第10章 类库和C+的标准模板库STL第11章 输入输出流第12章 异常处理,第5章 堆与复制构造函数,5.1 堆5.2 需要new和delete的原因5.3 默认的复制构造函数5.4 自定义复制构造函数,5.1 堆 Heap,堆是按动态方式分配的内存区域。在程序中需要空间存放数据时,就申请动态内存单元,使用完毕后释放动态内存单元。这种动态内存分配方式能够显著地提高内存的利用率。,C
2、+程序的内存布局,Stack 栈,Heap 堆,Global data 全局数据区,程序代码区program code,代码区存放程序的代码(可执行指令);,全局数据区存放全局变量、静态变量、常量。,固定存储区域,栈是存放程序中的所有动态局部变量、函数参数、函数返回值等信息的一块内存区域。,在固定存储区域与堆栈之间的自由区域称为堆,栈 Stack,栈的内存管理严格遵循后进先出(LIFO:Last in,First Out)的顺序,即释放栈中对象所占内存时的顺序刚好与给这些对象分配栈中内存时的顺序相反,这一点正是实现函数调用所需要的。从栈中分配内存效率特别高,对栈的充分利用是C/C+编译程序能产
3、生优质高效代码的原因之一。,动态内存分配,堆的内存是以动态分配方式管理的。所谓动态分配的内存是在程序运行期间获得的。动态存储分配方式允许我们的程序可以在执行期间根据实际的需要存放的数据量来申请合适数量的内存单元。这种动态分配方式不但能够提高内存的利用率,而且对于链表和二叉树等动态数据结构特别有用。,动态内存申请和释放,用函数malloc()分配的动态内存必须用函数free()释放;用new申请的动态内存必须用delete 释放。因为在C+程序中,从堆中获取的内存单元不会被自动释放,因此必须使用函数free()或者用delete释放这种内存。如果从堆中获取的内存在使用完后没有被释放,这部分内存在
4、程序结束之前会一直被占用,这种情况被称为“内存泄漏”。,5.2 需要new和delete的原因,5.2.1 需要new和delete的原因5.2.2 在堆上创建对象,5.2.1 需要new和delete的原因,对自定义的类类型,使用函数malloc()给对象分配动态空间时不能自动调用构造函数;使用函数free()释放对象所占用的动态空间时也不能调用析构函数。C+语言创建了new和delete两个运算符来满足面向对象的新特性,在C+语言程序中,我们应该使用new和delete来创建和销毁类的对象。,5.2.2 在堆上创建对象,使用new运算符在堆上创建对象时能够自动调用构造函数进行初始化;使用
5、delete运算符释放对象占用的动态内存时能够自动调用该对象的析构函数进行善后处理。,【例5.1】在堆上创建对象,#include using namespace std;class Square int side;public:Square(int x)side=x;coutConstructiongn;Square()coutDestructiongn;void display()cout side n;,【例5.1】在堆上创建对象(续),int main()Square*ps=new Square(10);/分配堆内存并调用构造函数初始化 ps-display();delete ps;/
6、自动调用析构函数,然后释放堆内存 return 0;该程序运行后的输出结果如下:Constructiong10Destructiong,【例5.2】传值调用例子,class Square int side;public:Square(int x)side=x;coutConstructiongn;Square()coutDestructiongn;void display()cout side n;void f(Square ob)/对象作为函数参数 ob.display();,【例5.2】传值调用例子(续),int main()Square s(10);f(s);/对象s以传值方式传送给临时
7、对象obs.display();return 0;该程序运行后的输出结果如下:Constructiong10DestructiongDestructiong10,对象的副本,当一个对象被作为参数传递给函数时,同时也创建了该对象的副本这个副本将成为函数的参数。也就是说,创建了一个新的对象。当函数结束时,作为函数的实际参数的副本将被销毁。也就是说,一个对象被销毁了,两个问题,第一个问题:在创建对象的副本时是否调用了构造函数?第二个问题:当销毁对象的副本时是否调用了析构函数?,第一个问题的答案,首先,在调用函数的时候,程序创建了一个对象的副本作为形式参数,此时普通的构造函数(normal const
8、ructor)并没有被调用,而是复制构造函数(copy constructor)被调用。,为什么需要复制构造函数,由于普通的构造函数通常用于初始化对象的某些成员,因此就不能调用普通构造函数创建对象的副本,因为这样产生的对象可能与现有的对象不完全相同。当把一个对象传递给函数时,我们需要使用的是对象的当前状态,而不是初始状态,5.3 默认的复制构造函数,复制构造函数定义了如何创建一个对象的副本。如果一个类中没有显式地定义类的复制构造函数,那么C+将提供一个默认的复制构造函数(default copy constructor)。默认的复制构造函数将以按位复制的形式创建一个对象的副本,即创建一个与原对
9、象一模一样的副本。,第二个问题的答案,当函数结束时,由于作为参数的对象副本超出了作用域,因此它将被销毁,从而调用了析构函数。,结论,当创建一个对象的副本作为函数的参数时,复制构造函数被调用。当对象的副本被销毁时(通常因为函数返回而超出作用域),析构函数被调用。,自定义复制构造函数的例子,Square(const Square,如果程序员自定义了一个复制构造函数,编译时将不会产生默认的复制构造函数。,【例5.2】的另一种版本,class Square int side;public:Square(int x)side=x;coutConstructiongn;Square(const Squar
10、e,【例5.2】的另一种版本(续),int main()Square s(10);f(s);/对象s以传值方式传送给临时对象obs.display();return 0;该程序运行后的输出结果如下:ConstructiongCopy Constructiong10Destructiong10Destructiong,自定义复制构造函数,在很多情况下,使用按位复制的方法来创建一个相同的对象副本是可行的,这时我们可以直接使用C+语言提供的默认复制构造函数。但是,在某些情况下使用默认的复制构造函数会出现问题(例如【例5.3】),这时我们需要自己创建复制构造函数。,【例5.3】,class my_st
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 堆与复制构造函数 复制 构造 函数 PPT 课件

链接地址:https://www.31ppt.com/p-5631501.html