ImageVerifierCode 换一换
格式:DOCX , 页数:40 ,大小:31.27KB ,
资源ID:10259121      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/10259121.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(C++课程总结.docx)为本站会员(b****7)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

C++课程总结.docx

1、C+课程总结2012年度课程总结1.教学要求2.面向对象程序设计语言基础3.类和对象4.继承和派生5.多态与重载6.构造函数、析构函数与成员初始化7.DAG、内存存储内容和访问控制表8.运算符重载与静态联编9.虚函数与动态联编10.静态成员与堆的动态管理 1. 教学要求A.掌握面向对象程序设计的基本概念和原理:封装性继承性多态性B.具备阅读和理解程序的能力,初步掌握编程技术熟悉面向对象程序设计基本语言,同时熟悉派生类的访问控制表、基类及其派生类构造函数的调用顺序、基类及其派生类对象的内存存储内容、虚函数的功能、静态成员及堆空间的使用。2.面向对象程序设计语言基础1. 标识符与标点符号A.标识符

2、是由若干个字符组成的字符序列,用来命名程序中的一些实体。关键字是系统预定义的具有特定含义的标识符。语法规则:由字母(az, AZ)、数字(09)或下划线(-)组成第一个字符必须是字母、下划线或标识符中可包含关键字(如intx、myclass等),关键字不能作为新的标识符出现(如class、C#中的base等)B.标点符号本身不表示一个产生值的操作。常用的标点符号:,逗号,用作数据之间的分隔符;分号,语句结束符:冒号,语句标号结束符或条件运算符单引号,字符常量标记符双引号,字符串常量标记符左花括号,复合语句开始标记符右花括号,复合语句结束标记符C.使用“;”的场合:结构、联合和类的定义:stru

3、ct str;union uni;class base ;class derive:public base ;每条程序语句结尾:int i;couti;fun(i);函数原型说明:void fun(int, char *);double& fun(double&, char *);D. 不使用“;”的场合:预处理语句:include endif函数体(函数定义):void fun(int i, char *ptr) double& fun(double& d, char *ptr) return d; 程序控制语句:if (p) coutp; for ( int i=0; i10; i+) c

4、outi”来实现)。4.继承和派生1 派生类及其对象A. 派生类除了能从基类继承所有成员以外,还具有以下功能:1 增加新的数据成员2 增加新的成员函数3 重新定义成员函数4 改变现有成员的属性B. 建立派生类后,派生类对象的内存存储内容既包括基类的也包括派生类的所有非静态数据成员,这些数据成员中不管是否能够访问,都一律存放在派生类对象的内存存储区内。非静态数据的排列顺序是基类在前,派生类在后。如果有虚函数,则还包括虚指针VPTR,该虚指针指向vtable。2 派生类对基类成员的访问规则A. 基类中的私有成员在派生类中是隐藏的,只能在基类内部访问,这与继承方式无关B. 派生类中的成员不能访问基类

5、中的私有成员,可以访问基类中的公有成员和保护成员,此时访问能力与继承方式无关C. 派生类从基类公有继承时,基类的公有成员和保护成员在派生类中属性不变,基类的私有成员不可访问D. 派生类从基类私有继承时,基类的公有成员和保护成员在派生类中都改变为私有成员,基类的私有成员不可访问E. 派生类从基类保护继承时,基类的的公有成员在派生类中改变为保护成员,基类的保护成员属性不变,基类的私有成员不可访问3 多重继承与多接口继承A. 多重继承可以看成是C+中单继承的扩展,派生类与每个基类之间的关系仍可看作是一个单继承。如果想使公共的基类只产生一个拷贝,则可以把它声明为虚基类。B. 多接口继承是C#中单继承的

6、扩展,派生类只有一个基类(抽象类)但有多个接口实现方法,继承时排列顺序是先抽象类后接口5.多态与重载1 函数与运算符重载A. 静态联编函数重载是指同名函数的不同实现版本,在定义重载函数时,相同函数名的参数个数或类型必须相异(否则,出现二义性)B. 派生类对象访问同名成员函数的支配规则:1 其它函数访问对象成员时,先访问本类对象中的同名成员2 如果本类对象中没有该同名成员,则进而访问该对象直接基类的同名成员3 如果该对象的直接基类中仍然没有该同名成员,则不断上溯至该对象的间接基类中寻找,直至找到为止4 如仍找不到,则出现编译错误C. 运算符重载使用同一个运算符作用于不同类型的数据产生不同的行为,

7、实质是函数重载。重载规则:1 重载的功能应与原有功能类似2 操作数必须是定义它的类的对象3 不能改变运算符的操作个数4 不能改变运算符的优先级和结合特性5 不能改变对预定义类型数据的操作方式2 虚函数虚函数允许函数调用与函数体之间的联系在运行时才建立,即在运行时才决定如何动作,也就是所谓的动态联编。静态联编时,基类中的指针或引用不可调用派生类函数;动态联编时,基类中的指针或引用可以调用派生类中的虚函数。在派生类中重写虚函数实现版本时,其函数原型(包括返回类型、函数名、参数个数、参数类型、参数顺序等)都必须与基类中的原型完全相同。3 纯虚函数和抽象类A. 纯虚函数是一个在基类中说明的虚函数,但它

8、在基类中没有定义。纯虚函数是虚函数的特殊形式,对它的调用也是通过动态联编来实现的,不同的是纯虚函数在基类中完全是空的,调用的总是派生类中的定义。B. 抽象类的使用规定:1 抽象类只能作为其它类的基类使用,不能建立抽象类对象,其纯虚函数的实现由派生类给出2 抽象类不能用作参数类型、返回类型或显示转换的类型3 不允许从具体类(不包含纯虚函数的普通类)派生抽象类4 可以声明指向抽象类的指针或引用,该指针或引用可以指向其派生类5 C+抽象类可以继承(因为纯虚函数可以继承),C#抽象类不能继承(因为抽象方法不能继承)6 抽象类中可以定义普通成员函数或虚函数,而且可以通过派生类对象来调用不是纯虚函数的函数

9、6.构造函数、析构函数与成员初始化1构造函数A.类中地位:类中的特殊成员函数。一般提到成员函数时,不包括构造函数。B.定义格式:类内类名(形参列表):成员初始化列表 C+类外类名:类名(形参列表):成员初始化列表C.特点:名字与类名相同,但没有返回值可以有零个至多个参数可以重载不能继承D.基本功能:将对象的非静态数据初始化(静态数据、引用和子对象不能通过构造函数初始化)。将初始值从派生类传递给对象中基类部分的数据成员。必要时向堆申请空间(如带缺省参数的构造函数初始化对象数组)。E.调用顺序:C+:先虚基类祖先的客人,再虚基类祖先,再非虚基类祖先的客人和非虚基类祖先,然后自己的客人,最后自己。例

10、如:class A ;class B:virtual public A ;class C:virtual public A ;class M ;class P ;class D:public B, public C public:D () : B(), C(), A(), part(), member() /构造函数M member;P part; ;void main( ) D dd; 类定义中蓝色字体决定调用顺序构造函数调用顺序为:A B C M P D应该注意:a 在同一层中,祖先的构造函数中先调用虚基类的。b客人构造函数的调用顺序决定于它们在类中的声明顺序,和初始化列表中的顺序无关。例

11、如:class D:public B, public C public:D () : B(), C(), A(), part(), member() /构造函数M member;P part; ;先调用class M(member)的构造函数,再调用class P(part)的构造函数。而和part(), member() 的顺序无关。C#:先自己的客人,再祖先的客人,然后祖先,最后自己。例如:class A M mA=new M(); ;class B: A M mB=new M(); ;class C: B M mC=new M(); ;class M ;void main( ) C ob

12、j=new C(); 类定义中蓝色字体决定调用顺序构造函数调用顺序为:mC mB mA A B C2析构函数A.类中地位:类中的特殊成员函数。一般提到成员函数时,不包括析构函数。B. 主要功能:如构造函数曾经向堆申请空间,则析构函数调用delete函数(C+)或Dispose()方法将空间退还给堆。必要时析构函数应能为虚函数。C.调用顺序:C+:与构造函数调用顺序正好相反。C#:先客人,后家族,且分别与构造函数调用顺序相反。3成员初始化A.类成员的初始化顺序C+:基类对象成员初始化 基类成员变量初始化 派生类对象成员初始化 派生类成员变量初始化C#:派生类静态成员变量初始化 派生类实例变量初始

13、化 基类静态成员变量初始化 基类实例变量初始化 基类成员变量初始化 派生类成员变量初始化B.成员初始化列表主要用于向直接基类(包括C+虚基类)传递参数成员初始化列表的顺序可任意安排成员初始化列表中的参数(称传递参数)和直接基类(包括C+虚基类)中构造函数的形参必须两同:数量相同、类型相同(顺序相同),但传递参数和基类形参的名称可同可不同(一般都不同)C+中无虚基类时不准越级传递参数;有虚基类时必须越级直接传递参数给虚基类以4.5参数传递的习惯(规则)中的例4-17-2五层派生类中的虚基类为例:/ vir_cls9.cpp/ Initialization of argument of virtu

14、al base of five levels of derived classes#include class Bpublic: B(int i) ;class V: public Bpublic: V(int i, int j):B(i) ;class X: virtual public Vpublic: X(int i, int j):V(i, j) ;class Y: virtual public Vpublic: Y(int i, int j):V(i, j) ;class W : public X, public Ypublic: W(int a, int b, int c, int

15、 d, int e, int f): X(a, b), Y(c, d), V(e, f) ;class Z : public Wpublic: Z(int a, int b, int c, int d, int e, int f, int g): W(b, c, d, e, f, g), V(f, g) ;void main() Z obj(1, 2, 3, 4, 5, 6, 7); /* Result: 6 7 (nor 6 nor 2 nor 4) 3 5 2 1 */DAGB:B(i)V:V(i, j):B(i) X:X (i,j):V(i,j) Y:Y(i,j):V(i,j) W:W(

16、a,b,c,d,e,f) :X(a, b), Y(c, d), V(e,f )Z:Z(a,b,c,d,e,f,g) :W(b,c,d,e,f,g), V(f,g)其中 表示派生关系 表示参数传递此处间接基类V是虚基类,则Z、W必须直接向V传递参数。又如:D:D (int a, int b, int c, int d): B(a), C(b), member(c), part(d) 此处客人必须用对象名。因间接基类A不是虚基类,所以D不能直接向其间接基类A传递参数。7.DAG、内存存储内容和访问控制表7-1.DAG(有向无环图)用于表示继承关系。应注意C+中有无虚基类,如无虚基类则可能有多个同名

17、间接基类。例如下图中的class base:DAGbasebasepublic publicderive2derive1public publicgrand多继承类型对象内存存储内容DAG无虚基类两个以上相同基类数据有虚基类只有一个相同基类数据不同DAG决定了不同的内存存储内容和不同的构造函数调用顺序。也可以附加箭头来表示参数传递关系和构造函数调用顺序。答题时,如未提出要表示参数传递关系和构造函数调用顺序,则可不画。7-2.内存存储内容1.建立一个对象时,系统只在该对象的内存存储区(栈区或堆区)中存储其非静态数据成员而不存储对象的静态数据和成员函数,因静态数据和成员函数是同类的所有对象所共享的

18、。2.内存存储内容既包括基类的也包括派生类的所有非静态数据成员,这些非静态数据成员中不管是否能够访问,都一律存放在内存存储区内。排列顺序是基类在前,派生类在后且C+取决于派生类中各数据的声明顺序,C#先客人再祖先后自己。*3.如果有虚函数,则还包括该内存存储区内的虚指针VPTR(VPTR一般位于内存存储区的首部);数据区内的vtable(虚地址表)(其中存放各虚函数的地址);以及代码区内的各虚函数。这三个区应该区别开。基类和各派生类的各个vtable中各虚函数地址的存放顺序必须完全相同。*4.当对象内存存储区大于4个字节时,内存存储区以4个字节为增量。如下:/ obj_size_2.cpp/

19、To see how many bytes class A occupies/ there seems to be a 4-byte boundary#include class A int i; char ch1;void main() coutsizeof(A):sizeof(A)endl;/* Results:sizeof(A):8 */应注意:存放在栈区内的非静态数据、存放在堆区内的数据(用new分配的)和存放在数据区内的静态数据和全局变量这三者不应放在一起。(区名记不住不要紧)为能准确地确定内存存储内容,最好先画出DAG。7-3.访问控制表见第四章4.2“派生类成员函数及其访问控制”

20、类成员的访问控制符:缺省值为私有,可声明为公有或保护;私有(private)成员:只能由同一类的成员函数和友员函数访问,不准派生类成员函数和外部函数访问;公有(public)成员:可由任何函数访问;保护(protected)成员:除与私有成员相同外,还允许派生类成员函数访问,但不准外部函数访问。重要注解此处外部函数系指主程序(主函数)、其他类的成员函数和普通函数等。访 属 问 性 权 继承publlicprotectedprivatepublicpublicprotected不可访问C+privateprivateprivate不可访问protectedprotectedprotected不可

21、访问其中“属性”即基类成员的访问属性b_am,“继承”即派生类的继承方式inh_m,“访问权”即访问权限der_am,也即基类成员的访问权限在派生类中的映射。结合例4-4程序来分析三者关系class BASE int x1;public BASE(int a) x1 = a; public inc() return x1; ;class DERIVED : BASE int x2; public DERIVED(int a, int b) : base(a) x2 = b; ;class GRAND : DERIVED int x3; public GRAND(int a, int b, in

22、t c) : base(a, b) x3 = c; ;private void Form1_Load(object sender, EventArgs e) BASE p = new BASE(5); DERIVED der = new DERIVED(7, 11); GRAND gr = new GRAND(3, 6, 9); DAGBASEpublicDERIVEDpublicGRAND 对象p 对象der 对象grd2.x3=9d1.x2=11p.x1=5访问控制表class namepublicprivateinhclass BASEinc( )x1class DERIVED : ba

23、sex2inc( )class GRAND : basex3制作访问控制表的要点1.既有数据(包括静态数据)又有成员函数。2.既包括本派生类的数据和成员函数,又包括直接和间接基类的数据和成员函数。但以上两项只包括允许访问的数据和成员函数。3.成员函数只需标出函数名加( )即可,不必填入形参,最多写()。4.虚函数只需写本派生类的一个,因this指针只指向这一个。5.直接和间接基类的成员函数中如有同名者,必须加上类名以避免二义性,例如D2:display( )。访问控制表和内存存储内容的区别:派生类的访问控制表:1.只显示符合访问权限的允许访问的数据成员(包括静态数据)和成员函数。2.所有这些允

24、许访问的数据成员和成员函数既包括该派生类的又包括各基类(直接基类和间接基类)的。3. 但不包括虚指针。虚函数也可只显示本派生类的。派生类对象的内存存储内容:1.既包括该派生类的又包括各基类(直接基类和间接基类)的所有非静态数据(无论是否允许访问都应包括在内)。2. 如果有虚函数,则还包括对象内存存储区内的虚指针VPTR;数据区内的vtable(虚地址表);以及代码区内的各虚函数。这三个区应该区别开。3.不包括任何静态数据和成员函数。8.C+虚基类(一) 如何识别虚基类?虚基类的定义不出现在它自己的类定义首部,而因它主要用于多继承的情况,所以virtual关键词出现在至少两个或更多个它的的派生类

25、首部,例如:class A ;class B1 : virtual public A ;class B2 : virtual public A ;此时A就是虚基类。(二)虚基类的用途:A. 在多继承中,主要用于避免二义性。例1没有虚基类的例子#include class Apublic: int a; ;class B1 : public A int b1; ;class B2 : public A int b2; ;class C : public B1, public B2 int c; ;void main() C obj; DAGAApublic publicB2B1public publicC构造函数调用顺序:A B1 A B2 C class C对象c的存储内容c.A:a(B1)c.B1:b1c.A:a(B2)c.B2:b2c

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1