动态内存管理技术课件.ppt
《动态内存管理技术课件.ppt》由会员分享,可在线阅读,更多相关《动态内存管理技术课件.ppt(105页珍藏版)》请在三一办公上搜索。
1、2023/3/31,1,动态内存管理技术,C+常见问题,1,3,2,Const的使用,内联函数的使用,使用引用,4,类型转换,5,异常处理,6,命名空间,7,内容提要,2023/3/31,2,6.1内联函数的使用,6.1.1 内联函数引入的原因 调用函数时,要跳到函数的起始地址去执行,执行完函数的代码后,再返回到调用点继续执行。这种跳转操作需要保存现场及返回地址;返回时,又需要恢复现场。函数调用需要一定的时间开销和空间开销,这会影响程序的执行效率。,外联开销,2023/3/31,3,对内联函数,编译器会在程序出现内联函数调用的地方用函数体直接进行替换。目标程序将不存在调用问题,也就不会产生跳转
2、的问题,自然就不存在函数调用所需要的时间和空间开销。在编译时用函数代码替换到调用处,如果函数代码长度比较长,超过了跳转语句所占空间的长度,这自然会增加整个程序的代码量,进而增加了空间的开销。,实质是用空间换时间。,6.1内联函数的使用,2023/3/31,4,6.1.2 内联函数的定义 例6_1:smain6_1.cpp/1、全局函数定义为内联函数inline double Show1(double dX)return dX*dX;,6.1内联函数的使用,2023/3/31,5,/2、在类声明体内实现的函数不用inline关键字,自动是内联函数。double Show2(double dX)c
3、onstreturn dX*dX;,6.1内联函数的使用,2023/3/31,6,/3、在函数声明处可加可不加inline关键字。double Show3(double dX)const;/4、但在实现处必须加inline关键字inline double CPerson:Show3(double dX)constreturn dX*dX;,6.1内联函数的使用,2023/3/31,7,内联函数使用时注意以下几点。1、在内联函数中不允许用循环语句、开关语句和递归调用语句等。2、内联函数的定义必须出现在第一次调用内联函数之前。3、在类内部定义并实现的成员函数自动是内联函数,但在类内定义成员函数时,
4、如果使用了for()、while()、do while()、switch()等语句,该成员函数会自动转为非内联函数。4、内联函数中不能够有静态数据。5、内联函数中不能够有数组说明。,6.1内联函数的使用,2023/3/31,8,6.1.3 内联和非内联函数的选择使用内联函数时间开销的减少,以空间的消耗为代价,而且执行效率的提高也不是绝对的。在决定使用内联函数时要进行适当的取舍。不是所有的函数都适合采用内联函数。构造函数和析构函数常常就不适合内联,这是因为构造函数和析构函数在编译时,往往会被编译器附加一大堆代码。,全部内联可以吗?,6.1内联函数的使用,2023/3/31,9,看看CStuden
5、t类的构造函数:例6_2:构造函数、析构函数往往不适合作内联函数。smain6_2.cpp,构造函数、析构函数最好不要内联。,6.1内联函数的使用,2023/3/31,10,CStudent()构造函数看起来是空的,但它可能含有相当多的代码(与编译器的设计有关)。CStudent的构造函数,需要构建4000字节的空间,并且还需要按照基类的要求初始化这些空间,因此它包含了一个复杂的创建过程。构造函数和析构函数最好都在类内声明,类外实现。一般来说,实际编程时最好是不要内联任何函数,除非函数确实很小很简单。,不要内联任何函数,6.1内联函数的使用,2023/3/31,11,6.2 const的使用,
6、const意味着分配了一块不可改变的内存。用const定义或说明常类型量时必须初始化。常类型量,也就是常量。const更重要的用途则在于说明函数参数以及函数返回类型。,函数参数,2023/3/31,12,const主要有以下几种用法:1、const说明值常量。2、const说明指针。3、const说明函数参数及其返回值。4、const说明类中的常量和成员函数。,6.2 const的使用,2023/3/31,13,6.2.1 const说明值常量 1、说明符号常量,表明符号代表的是一个常量,说明格式如下:double const PI=12;const double PI=12;2、说明数组常量
7、,说明格式如下:const int I_ARRAY=3,2,1;3、说明对象常量,说明格式如下:const CInline1 oC1,oC2;在一排逗号隔开的变量中,只需要一个const就行了,在前、在后定义都可以。,6.2 const的使用,2023/3/31,14,const与C语言#define的差别:#define PI 3.14无参宏不是符号常量,它没有数据类型,没有值,在内存中不分配地址。它是在预处理时作宏替换,不作类型检查。而const定义的常量是符号常量,有数据类型,有值,且其值不可改变,在内存中有地址,编译时要作类型检查。,6.2 const的使用,2023/3/31,15,
8、6.2.2 const与指针 指针涉及三个东西:一个是指针变量本身;另一个是指针指针变量中所存放的值;再一个就是指针所指向的对象。,6.2 const的使用,2023/3/31,16,指针其实就是地址,它代表的是指针变量中存放的地址值;而指针变量是指用来存放指针的一个变量,它用来存放地址;注意:指针变量本身也有地址,有存储单元;指针所指向的对象是指那片空间所“存放的东西”。指针变量本身的地址,与指针变量所指向的对象的存储地址是两个不同的地址。,6.2 const的使用,2023/3/31,17,6.2 const的使用,2023/3/31,18,const和指针变量的典型组合有以下三种情况:1
9、、指向常量的指针 const int*p;2、常指针 char*const pc=a;3、指向常量的常指针const char*const pc=a;,6.2 const的使用,2023/3/31,19,const int*p;char*const pc=a;const char*const pc=a;画一条垂直线穿过指针声明中的星号(*)位置。如果const出现在线的左边,则指针指向的对象为常量;如果const出现在线的右边,则指针本身为常量;如果const在线的两边都出现,则二者都是常量,是指向常量的常指针。,6.2 const的使用,2023/3/31,20,1 指向常量的指针 指针指向
10、一个不可改变的量。指向常量。在声明时可以不初始化。该指针可以指向这个常量,也可以指向另一个常量。指针变量里的指针值是可以改变的;但某一个具体指针值(即:某个指针)所指向的那个对象则是不可以改变的。,对象不可改变。,6.2 const的使用,2023/3/31,21,它也可以指向变量;从指针角度而言,所指向的是一个常量,通过该指针不能修改它所指向的对象;该指针变量可以存放常量地址也可以存放变量地址。,对象不可改变。,6.2 const的使用,2023/3/31,22,const char*pc=ABCD;pc3=a;/不可以。pc=“EFGH”;/可以/step是一个指向常量的指针数组 cons
11、t char*step3=left,right,top;step2=skip;/可以。step21=i;/不可以。,6.2 const的使用,2023/3/31,23,2 常指针*const=;指针变量里面存放的是个常量,称为常指针,指针变量里面装的是一个固定值,在定义时必须初始化。常指针一旦初始化后,不能够再指向其他内存单元。通过常指针可以修改它所指向的内存单元的内容,也就是修改常指针所指向的对象。,6.2 const的使用,2023/3/31,24,char*const pc=ABCD;/常指针pc3=a;/可以。pc=EFGH;/不可以/step是一个常指针数组 char*const s
12、tep3=left,right,top;step2=skip;/不可以。step21=i;/可以。,6.2 const的使用,2023/3/31,25,3 指向常量的常指针 指针本身及指针所指向的对象都不可改变。二者都要声明为 const。在声明时必须初始化。指针本身及其指向的对象均不能改变。const char*const pc=asdf;pc3=a;/不可以。pc=ABCD;/不可以。,6.2 const的使用,2023/3/31,26,6.2.3 const说明函数参数和返回值是const最重要的应用。在值传递场合不必用const。用const去修饰用指针和引用传递的函数参数,是安全的。
13、const修饰函数的返回值。,安全的,6.2 const的使用,2023/3/31,27,void Func(const char*lpszChar);void Func(char const*lpszChar);/以上二者等价。/参数是对象的常引用,返回值也是一个对象的常引用。const CStudent 对返回值使用const也有可能提高函数的安全性和效率。,6.2 const的使用,2023/3/31,28,6.2.4 类中的const在类中,const的使用也比较广。它可以用于修饰类中的成员函数和成员数据。,主要应用,6.2 const的使用,2023/3/31,29,1 常成员函数
14、不可以改变对象数据成员的函数。在一般成员函数后面加上const即可。1、用const关键词修饰一个成员函数,说明该成员函数是“只读”的。2、只有常成员函数可以操作常对象,常对象只能调用常成员函数(const成员函数)。3、一般对象不但可以调用一般成员函数,也可以调用常成员函数。,6.2 const的使用,2023/3/31,30,例6_3:常对象只能够调用常成员函数,不能够调用一般成员函数,而一般对象可以调用所有的成员函数。s6_3sclass6_3_T.h s6_3sclass6_3_point.cpp s6_3smain6_3.cpp运行结果,一般成员函数调用:1 2一般成员函数调用:2
15、3 常成员函数调用:3 3,6.2 const的使用,2023/3/31,31,例子表明:仅在const方面有不同的成员函数是可以重载的,编译器能够正确区分这两个函数。而对调用对象来说,一般对象优先调用重载的一般函数,其次才是const函数;常对象(const对象)则只能够调用const函数,不能够调用一般函数。对于一般对象,当调用一般成员函数不成功时,系统自动会转入对常成员函数的调用。,6.2 const的使用,2023/3/31,32,2 常数据成员若一个数据成员的前面用了关键词const修饰符,则该数据成员为常数据成员。const 型的数据必须初始化,且不能修改,它是常数据成员。常数据成
16、员的初始化方式在定义对象时,通过在构造函数后面加上成员初始化列表来完成的。smain6_4.cpp,6.2 const的使用,2023/3/31,33,class CPoint/CPoint类private:int m_x;/x坐标const int m_y;/y坐标,常数据成员static const int m_z;/z坐标,静态常数据成员;const int CPoint:m_z=0;/静态数据成员的初始化方式。/构造函数,m_y采用了初始化表的方式初始化。CPoint:CPoint(int x,int y):m_y(y)m_x=x;/正确。/m_y=y;/错。,6.2 const的使用
17、,2023/3/31,34,在CPoint中设置了空间坐标中的m_x、m_y和m_z坐标。分别把它们设置成一般数据成员、常数据成员和静态常数据成员。由于类型不同,它们所采用的初始化方式是很不一样的。在设计构造函数时,最好对一般成员数据也采用初始化表的方式进行初始化。这样效率最高。,6.2 const的使用,2023/3/31,35,3 常对象常对象就是其值不可改变的对象。它是只可以取值不可以修改的对象。常对象一旦建立并初始化以后,只可以通过常成员函数来访问它。const CPoint ocCPoint3(3,3);,6.2 const的使用,2023/3/31,36,6.3 动态内存管理技术,
18、动态对象就是程序在运行过程中在动态内存中建立的对象。这类对象需要用户自己使用new运算符创建,使用delete运算符释放,需要用户自己管理。,堆,栈,静态内存,2023/3/31,37,6.3.1 内存的几种分配方式计算机内存通常具有三种组织方式:堆、栈和静态内存。1、在静态存储区中分配。静态存储区中的变量空间在编译时分配。静态内存区中的变量在程序的整个运行期间都存在。其生命周期贯穿整个程序的运行周期。例如全局变量,static变量等在这个区间分配。,6.3 动态内存管理技术,2023/3/31,38,2、在栈上分配自动变量等局部变量在栈上分配存储空间。函数内的局部变量在栈上分配存储单元。它的
19、生命周期与函数的执行时间相同。当函数执行结束时这些存储单元会被自动释放,其生命周期也就完结了。,6.3 动态内存管理技术,2023/3/31,39,3、在堆上分配,亦称动态内存分配。动态内存由程序员自己负责管理。运行时用new申请内存。程序员负责在不需要时用delete释放内存。,比拉登还麻烦。容易出问题。,6.3 动态内存管理技术,2023/3/31,40,6.3.2 使用new和delete分配和释放动态内存malloc()与free()标准库函数;new/delete运算符(不是库函数)。malloc()/free()功能有限。用户自定义类型在创建对象时要执行构造函数,对象在消亡之前要执
20、行析构函数。而且是自动执行的。所以,C+使用能完成动态内存分配和初始化工作的运算符new,及能完成清理与释放内存工作的运算符delete来管理动态内存。,6.3 动态内存管理技术,2023/3/31,41,6.3.2.1 new运算符 new用来动态地分配存储空间。它能够自动计算要分配的存储空间大小并能返回正确的指针类型。若返回值为NULL,则表示动态内存分配不成功。在用new申请动态内存后,一定要判断动态内存是否分配成功。,if(p!=NULL),6.3 动态内存管理技术,2023/3/31,42,int*pInt1,*pInt2;pInt1=new int;/new 运算返回一整数单元的地
21、址pInt2=new int(200);/new一个int单元,并将其初始化为200。int*pInt3,(*pInt4)3;pInt3=new int10;/new 运算返回一整数单元的地址,有10个这样的单元。pInt4=new int23;/new 运算返回每行为3个元素的行地址CPoint*poCPoint;poCPoint=new CPoint(10,10);/new 运算返回对象的地址,并在动态内存中创建了一个对象。,6.3 动态内存管理技术,2023/3/31,43,使用new运算符创建数组时,不能为该数组指定初值。执行“CPoint poCPoint=new CPoint(10
22、,10);”语句时,得到了两个东西:一个是对象指针变量,另一个是在动态内存空间中的对象,而指针变量中的值,就是这个动态内存空间中的对象的首地址,也就是动态内存地址。而且这个对象是没有名字的,只有通过指针进行访问。,6.3 动态内存管理技术,2023/3/31,44,2 delete运算符delete释放new所分配的存储空间。是存放了要释放的存储空间地址的指针变量名字。释放new所创建数组时,使用“delete;”的形式。delete只能用来释放用new申请得的动态内存空间,而且一次new只能够对应一次delete。,配对使用,6.3 动态内存管理技术,2023/3/31,45,delete
23、pInt1;delete pInt2;delete pInt3;/释放用new申请的数组空间/释放由new申请的数组空间,对多维空间的释放格式与一维空间相同。delete pInt4;delete poCPoint;/释放一个对象,6.3 动态内存管理技术,2023/3/31,46,注意:delete后,指针所指向的内存空间就释放了,但指针变量的值并没有改变。指针还指向原来的内存空间。所以,delete以后,应将指针变量的值设置成NULL,让它不再指向原来的内存空间,以免误操作。例6_5:显示了new和delete的基本使用 smain6_5.cpp,6.3 动态内存管理技术,2023/3/3
24、1,47,CPoint*poCPoint;/创建对象时,自动调用构造函数。poCPoint=new CPointARRAY_SIZE;/判断动态内存申请是否成功。if(poCPoint=NULL)cout 动态内存分配失败。n;exit(0);/内存申请失败,则退出.,6.3 动态内存管理技术,2023/3/31,48,delete poCPoint;/释放对象数组。/动态内存释放后,让poCPoint指针指向NULL。否则,它依然指向原动态空间。poCPoint=NULL;,其内容为垃圾,6.3 动态内存管理技术,2023/3/31,49,在例6_5中,数组中的5个对象其坐标都是(0,0,0
25、)。这是由于给数组分配空间时,不能进行初始化(声明时不能够带参数)。也就是说:new一个对象数组时是不能够带参数的。缺省的参数则可以,构造函数缺省值为(0,0,0)。,6.3 动态内存管理技术,2023/3/31,50,对象数组的对象初始化有两种方法:1、在类中不定义构造函数,而定义一个成员函数专门用来完成初始化。2、在所定义的类中增加不带参数或带缺省参数的构造函数。,6.3 动态内存管理技术,2023/3/31,51,poCPoint=new CPointARRAY_SIZE;“表明对应着:delete poCPoint;;而:CTemp*poCTemp=new CTemp(5);”对应着:
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 动态 内存 管理 技术 课件

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