《面向对象程学设计》复习大纲Word格式.docx
《《面向对象程学设计》复习大纲Word格式.docx》由会员分享,可在线阅读,更多相关《《面向对象程学设计》复习大纲Word格式.docx(31页珍藏版)》请在冰豆网上搜索。
voidmyfunc(doubled=0.0){…}
myfunc(198.234);
//passanexplicitvalue
myfunc();
//letfunctionusedefault
②const修饰形参:
表示此参数在其所在的函数内为常量,即不可修改。
③内联/内嵌函数:
在函数声明或定义的前面加上关键字“inline”,该函数就被声明为内联函数。
④函数重载
●两或两个以上的函数使用同一个函数名,称为函数重载。
●函数重载的条件:
函数参数的类型或个数不同,即函数原型的参数列表不同
●只有函数返回值类型不同,不能重载
●函数重载与参数带默认值的函数一起使用时,有可能引起二义性,使用时要谨慎。
(4)new和delete运算符
①new运算符:
用于向系统申请动态存储空间,并返回正确类型的指针。
申请失败时,则返回0指针,使用new的语法格式:
指针变量=new数据类型标识符(初值)/[元素个数]
②delete运算符:
使用new申请得到的空间必须使用delete运算符进行释放,使用格式:
delete[]指针变量名
第3章类与对象
1.类的定义:
类的定义包括类的说明和类的实现两大部分。
说明部分提供了对该类所有数据成员和成员函数的描述;
实现部分则提供了所有成员函数的实现代码。
(1)类定义的格式:
class<
类名>
{private:
<
数据成员或成员函数>
protected:
public:
<
};
各成员函数的实现代码>
(2)说明:
①class是定义类的关键字,类名由用户自己定义,但应满足标识符的命名规则。
②与struct相比,类的说明部分添加了新内容:
成员函数的说明以及访问权限控制符:
public、protected、private。
●private部分:
该部分成员只允许被本类的成员函数访问或调用,在类外不能被直接访问。
一般情况下,类的数据成员多声明为private成员;
●public部分:
该部分成员允许被本类或其他类的成员函数(通过对象)访问或调用。
public成员多为成员函数,用来向外界提供一个接口,外界只能通过这个接口才可以实现对private成员的访问;
一个类的定义中应该含有public权限的成员,否则该类的定义无意义。
●protected部分:
该部分成员不能在类外访问,只允许被本类的成员函数及其子类(派生类)的成员函数访问或调用。
●当类成员未指明是哪部分时,默认为private成员。
●类中的每个成员只能被指定一种特定的访问控制权限。
③公有部分、私有部分和保护部分可以以任意顺序出现,且并非同时出现。
④类的说明部分以分号结束。
(3)成员函数的定义:
①在类的定义体外部定义成员函数,在类的定义体中声明成员函数定义时,需在函数名之前加上其所属的类名和作用域限定符“:
:
”,没加类名的函数默认为非成员函数(全局函数)。
②在类的定义体内部定义成员函数,系统自动使该成员函数成为内联函数。
在类定义体外部定义的成员函数若为内联函数,需用inline关键字指明。
(4)类成员的访问:
①类的数据成员和成员函数属于该类的类作用域(即使成员函数定义在类体之外),非成员函数在文件作用域中定义。
②在类作用域中,类成员可由该类的所有成员函数直接访问;
在类作用域外,访问类成员是通过一个对象的句柄实现的,可以是对象名、对象引用或对象指针。
利用对象的句柄访问类成员的运算符与访问结构体成员的运算符相同。
2.对象
对象是类的一个实例,当定义一个类时,只定义了这种数据类型,当程序中定义了数据类型的变量时,该变量就是该类的对象(或类的实例)。
(1)类对象的定义方法:
定义类的同时定义对象;
定义类后定义对象,单独定义对象的一般格式:
类名对象名表;
(2)对象的指针与引用:
①指向对象的指针变量的定义格式:
类名*变量名;
②对象引用的声明格式:
类名&
引用名=对象名;
(3)访问对象成员的方法:
①格式1:
对象名.公有成员名;
②格式2:
指针变量名->
公有成员名;
注意:
在类外不能对类的private成员和protected成员进行直接访问,可以通过其他public成员函数访问。
3.this指针
this指针是一个特殊的隐含指针,它指向当前对象,代表了对象的地址。
当对象调用类的非静态成员函数时,编译器会自动将对象本身的地址作为一个隐含参数传递给该函数,这个地址被一个隐含的形参this指针获取,函数调用中对对象成员的访问都隐含地被加上了前缀this->
。
显式使用this指针的语法格式:
this->
成员名;
4.构造函数
(1)功能:
创建对象时,实现对数据成员的初始化。
(2)定义格式:
类名(形参列表){函数体}
(3)特点:
①构造函数是类的成员函数,可以直接访问类的所有数据成员。
②构造函数与类同名,可以是无参函数,也可以是有参函数。
③构造函数不允许有返回值类型,即使是void也不可以。
④构造函数可以重载,为对象提供不同的初始化方法。
⑤构造函数应为公有函数(public)。
⑥声明类对象时,可以在对象名后面的括号中提供初始化值。
这些初始化值作为参数传递给类的构造函数。
⑦在创建类对象时,系统将自动调用构造函数以实现对数据成员的初始化。
⑧若类中没有显式定义构造函数,则编译时系统为该类提供一个默认的构造函数,它仅负责创建对象,不做任何初始化工作。
在用默认构造函数创建对象时,若创建的是全局对象或静态局部对象,则对象的默认值是0,否则对象的初始值不确定。
如果用户自定义了构造函数,则编译系统将不会再添加默认的构造函数。
⑨构造函数可以包含默认参数,这样即使对象定义时不提供初始值,对象也能利用默认参数进行初始化。
一个类只能有一个带默认参数的构造函数,在使用时要防止二义性。
(4)拷贝构造函数
①功能:
拷贝构造函数是一种特殊的构造函数,用于完成基于对象的同一类其他对象的构造及初始化。
②定义格式:
类名(const类名&
参数名)
{函数体}
③说明:
●拷贝构造函数只有一个参数,即该类对象的引用;
●拷贝构造函数的功能是用于实现对象值的拷贝,以完成对新对象的初始化,即用一个对象去构造另一个对象。
●如果定义类时没有定义拷贝构造函数,编译系统会自动为类添加一个默认的拷贝构造函数,用以完成浅拷贝。
●如果将对象作为函数的参数,或将对象作为函数的返回值,调用这两类函数时也会自动调用拷贝构造函数。
5.析构函数
析构函数是类的一个特殊的成员函数,在类对象的生命期即将结束时由系统自动调用,用来在对象被删除前做一些清理善后工作和数据保存工作。
其函数名是在类名前面加上代字符(~)。
~类名()
{函数体}
①析构函数没有返回值,也没有参数。
②一个类中只能有一个析构函数,没有重载。
③如果定义类时没有提供析构函数,系统会自动创建一个默认的析构函数。
当类对象中分配有动态内存时,则必须为该类提供适当的析构函数,以完成清理工作。
6.构造函数和析构函数的调用顺序
●构造函数和析构函数是由系统自动调用的,函数的调用顺序取决于过程进入和离开对象范围的顺序。
一般来说,析构函数的调用顺序与构造函数相反。
●对象的存储类型可以改变析构函数的调用顺序。
●全局对象的构造函数在程序开始执行之前调用,在程序结束时调用其析构函数;
●自动局部对象的构造函数在执行到对象定义时被调用,其析构函数则在离开定义对象的块时被调用;
●静态局部对象的构造函数在程序执行首次到达对象定义时调用一次,其析构函数在程序结束时被调用。
7.字符串类
(1)标准C++类库预定义了string字符串类,它封装了字符串的属性,并提供了访问属性的成员函数。
利用string可以直接声明字符串变量,并能进行字符串的赋值、相加、比较、查找、插入、删除、取子串等操作。
(2)使用string类时必须包含头文件string,并使用命名空间std。
(3)MFC中的CString类在功能上类似于标准C++的string类。
8.静态成员
(1)静态数据成员
同一个类的不同对象都有自己的数据成员的空间,它们可以具有不同的属性值(实例属性),当类的所有对象需要共享一个成员副本时(类属性),可以通过声明静态数据成员来实现。
①定义格式:
static类型标识符成员名;
②说明:
●类的静态数据成员是同一类的所有对象共有的。
不管有多少个对象,静态数据成员只有一个,同时可被任何一个同类对象访问。
●在一个类对象的空间内不包含静态数据成员的空间,其所占的空间不会随对象的产生而分配,或随对象的撤销而消失。
它是在程序开始时被分配的,即使没有创建类的一个对象。
●静态数据成员不具体属于哪一个对象,不能在构造函数或其它成员函数中初始化。
必须初始化且在类外进行,其语句不属于任何类、任何函数,其在文件范围内只能初始化一次,格式为:
类型标识符类名:
静态数据成员名=初值;
●对于在类的public部分声明的静态数据成员,可以不使用成员函数而通过对象直接访问,若未定义类的对象,需用类名指明。
访问格式为:
类名:
成员名
●在private和protected部分声明的静态数据成员只能通过类的成员函数访问。
若未定义类的对象,则需提供一个类的静态成员函数,并在调用时使用类名和作用域运算符指定。
(2)静态成员函数
其定义与一般成员函数的定义相同,只是在其前面需加上static修饰符。
●即使在类没有实例化任何对象时,类的静态数据成员和静态成员函数就已经存在并可使用。
●与静态数据成员一样,静态成员函数是独立于类对象而存在的,它不与类的对象相关联。
静态成员函数没有this指针。
访问静态成员函数时不需对象,但需在函数名前加上类名和作用域运算符。
●一个静态成员函数不与任何对象关联,因此,它不能对类中的非静态成员进行默认访问。
解决办法:
将对象作为静态成员函数的参数,在函数中通过对象访问其非静态成员。
9.对象成员(组合类)
(1)定义:
组合类是指一个类将其他类对象作为自己的数据成员。
其定义格式为:
classX
{类名1成员名1;
类名2成员名2;
……
};
(2)组合类构造函数的定义形式:
如果其成员对象的构造函数为有参函数时,组合类对象的构造函数参数表需指定传递给成员对象的参数,并利用初始化列表的方式显式调用对象成员的构造函数。
其定义形式为:
类名(对象成员形参,基本类型成员形参):
对象成员1(形参表1),对象成员2(形参表2),…
{基本类型成员的初始化}
(3)说明:
①组合类对象的构造函数首部中,各成员对象的初值表均来自于构造函数的形参表。
②组合类对象按照由内到外的顺序构造,按照由外到内的顺序删除。
③若一个类在定义中将它的成员对象指定为public,将不会破坏该成员对象的private成员的封装和隐藏。
④构造组合类对象的顺序:
系统首先调用内嵌成员对象的构造函数,依次初始化成员对象;
然后再执行组合类对象构造函数的函数体,对其他的非对象数据成员进行初始化。
若该组合类对象含有多个内嵌成员对象,则按类定义时的声明顺序构造成员对象,而不是按照初始化表中的顺序。
如果成员对象不需要提供初始值,系统将隐式调用其默认构造函数。
(4)组合类的拷贝构造函数:
如果没有为组合类定义一个拷贝构造函数,编译系统会自动为组合类添加一个默认的拷贝构造函数,其功能是:
自动调用内嵌对象的拷贝构造函数,对各内嵌对象成员进行初始化。
组合类拷贝构造函数的定义格式如下例:
C:
C(C&
c):
a(c.a)
{…}
第5章单继承与派生
1.继承的基本概念
继承是面向对象程序设计的一个重要特性,它允许在已有类的基础上创建新的类。
新类继承了现有类的属性和方法(不必重新编写代码),同时又添加了自己的新特性,从而在继承的基础上实现扩充。
2.基类与派生类:
在继承关系中,被继承的原有类称为基类(baseclass),又称为父类或超类;
通过继承关系定义出来的新类被称为派生类(derivedclass),又称为子类。
(1)单继承派生类的定义格式:
class派生类名:
[继承方式]基类名
{派生类中新成员的声明};
①“继承方式”可以是public、pretected或private方式,若缺省,则默认为private。
通过它可以实现派生类对继承自基类的成员的访问控制,通常多使用public继承方式。
②基类必须是已定义的一个类。
③派生类首部列出的是派生类的直接基类。
④派生类中成员:
●继承基类的成员;
●
增加新的成员;
●重新定义继承自基类的成员。
3.派生类对基类成员的访问控制
(1)说明:
①无论是哪种继承方式,基类的private成员在派生类中都是不可见的。
这符合数据封装和信息隐藏的思想。
②派生类虽然不能直接访问基类的private成员,但可以通过基类的public或protected成员函数间接访问。
③不同继承方式的影响主要体现为:
●派生类成员对基类成员的访问控制(类域内内部访问)
●派生类对象对基类成员的访问控制(类域外对象访问)
(2)私有继承的访问规则:
基类中的成员
公有成员
保护成员
私有成员
访问方式
内部访问
可访问
不可访问
对象访问
(3)公有继承的访问规则:
(4)保护继承的访问规则:
4.同名成员:
同名覆盖
在派生类中可以对从基类中继承的成员函数进行重新定义,使之满足派生类的具体需要。
——同名覆盖
通过派生类对象调用一个被重定义过的基类成员函数,被调用的是派生类的成员函数,此时若想调用基类的成员函数,必须使用基类名和作用域运算符加以限定。
5.派生类的构造函数和析构函数
派生类不能继承基类的构造函数和析构函数。
由于派生类继承了基类成员,在建立派生类的对象时,必须先调用(隐式或显式)基类的构造函数来初始化派生类对象的基类成员。
(1)派生类构造函数:
派生类名:
派生类构造函数名(形参表):
基类构造函数(参数表)
{函数体}
●调用基类构造函数的参数表来自于派生类构造函数的参数表中。
●若在基类中没有定义任何构造函数,则派生类的构造函数定义时可省略对基类构造函数的调用,在创建对象时,系统将隐式调用基类的默认构造函数;
如果基类构造函数存在,且为有参函数,则必须定义派生类的构造函数。
③构造函数的调用顺序:
a)在创建派生类对象时,系统首先调用基类的构造函数,初始化派生类中的基类成员;
b)若派生类包含对象成员,则调用对象成员的构造函数。
若包含多个成员对象,其调用顺序按照它们在类中的声明顺序;
派生类名(参数总表):
基类名(参数表0),对象成员名1(参数表1),….,对象成员名n(参数表n)
c)调用派生类的构造函数,初始化派生类中的新增数据成员;
(2)派生类析构函数
①定义方法与普通类的析构函数相同:
~派生类类名(){函数体}
②派生类析构函数的工作:
完成派生类对象的清理工作
③析构函数的调用顺序与构造过程相反:
a)调用派生类的析构函数,清理普通成员;
b)调用对象成员的析构函数,清理对象成员;
c)调用基类的析构函数,清理自基类继承来的成员。
6.基类与派生类对象之间的赋值兼容关系
(1)规则:
在需要基类对象的任何地方,都可以用公有派生类的对象替代,只能使用从基类继承来的成员,但反之则不被允许。
(2)具体体现:
①派生类对象可以向基类对象赋值,即用派生类对象中从基类继承来的数据成员逐个赋值给基类对象的数据成员。
②派生类对象可以初始化基类对象的引用。
③派生类对象的地址可以赋给指向基类对象的指针,即指向基类的指针也可以指向派生类对象。
(3)注意:
通过基类对象名、指针访问派生类对象时,只能访问从基类继承的成员。
(4)基类指针、派生类指针、基类对象、派生类对象的混合匹配有以下四种情况:
①直接用基类指针指向基类对象。
②直接用派生类指针指向派生类对象。
③用基类指针指向其派生类对象。
这种方式是安全的,但基类指针仅能访问派生类对象的基类部分。
④用派生类指针指向基类对象。
这种方式不被允许,会导致语法错误。
可以通过强制类型转换将基类指针转换为派生类指针,实现对基类对象的访问,但不安全,程序员需正确使用指针。
第6章多态性和虚函数
1.多态性
(1)概念:
是指同样的消息被不同对象接收时导致完全不同行为的现象。
这里的“消息”即对类成员函数的调用。
(以相同的指令却调用了不同的函数)
(2)种类:
①编译时的多态性:
静态联编
不论用类对象、对象指针或对象引用哪种形式访问成员函数(非虚函数),编译系统都根据它们的定义类型,在编译阶段进行静态绑定。
其方式为:
●通过在类中重载成员函数实现
●通过在派生类中重定义基类成员函数实现
②运行时的多态性:
动态联编
运行时的多态性是指在程序运行时根据运行所产生的信息决定调用哪个函数,它是在运行过程中发生的,编译系统在编译时是无法确定的,通过虚函数实现。
2.虚函数的定义与调用
(1)虚函数实现多态性的过程:
首先将基类中的某成员函数声明为虚函数,然后在每个派生类中重新定义此虚函数。
当客户通过基类指针(或引用)请求调用虚函数时,C++会在程序运行时根据所指对象的不同,自动地选择与之关联的派生类函数,实现调用。
(2)基类中声明虚函数的方法:
class类名
{……
virtual类型函数名(参数表);
……
};
①只有类的成员函数才能被声明为虚函数,其他全局函数和静态成员函数、类的构造函数不能声明为虚函数。
②若虚函数在类外定义,则定义时不能再加virtual关键字
③虚函数可以在多个派生类中被重定义,它属于函数重载的情况。
但与一般函数重载不同的是,它要求在派生类中重定义时的虚函数必须与基类定义中的虚函数原型完全相同。
否则,按普通函数重载看待。
④一旦一个基类成员函数被声明为虚函数,它从该点之后的继承层次结构中都是虚函数。
若派生类需重定义该虚函数,声明时可省略virtual关键字。
⑤没有重定义虚函数的派生类简单地继承其直接基类的虚函数。
⑥C++只对调用的虚函数进行动态绑定,而普通函数则是静态绑定。
3.虚析构函数
(1)虚析构函数解决的问题:
若基类指针指向的派生类对象是使用new运算动态生成的,如果没有将析构函数定义为虚函数,则在使用delete运算删除该派生类对象时,只会调用基类析构函数,而没有调用派生类的析构函数,从而无法完成正确的对象清理工作。
如果将基类的析构函数定义为虚函数,由该基类所派生的所有派生类的析构函数也都自动成为虚函数。
4.纯虚函数与抽象类
(1)纯虚函数:
只在基类中声明为虚函数,但未给出具体的函数定义。
纯虚函数的声明形式:
virtual类型函数名(参数表)=0;
(2)抽象类:
包含纯虚函数的类称为抽象类。
●不能建立抽象基类的实例化对象,但可以声明指向抽象基类的指针变量或引用,用以实现虚函数的运行时多态。
●抽象类中可以有多个纯虚函数。
●抽象类也可以定义其他非纯虚函数。
●如果在派生类中没有重新定义纯虚函数,则必须再次将该虚函数声明为纯虚函数,此时这个类仍是一个抽象类。
●从抽象类中可以派生出具体类或抽象类,但不能从具体类派生出抽象类。
第9章Windows编程基础和MFC编程基础
1.MFC应用程序的基本执行过程
(1)创建CTestApp类的全局对象theApp。
由于CTestApp是CWinApp类的派生类,因此在调用CTestApp的构造函数构造全局对象theApp之前,先调用CWinApp类的构造函数。
(2)调用应用程序的入口函数WinMain。
该函数已经在MFC中被定义,由链接器直接加到应用程序代码中。
(3)在AfxWinMain函数中调用CTestApp类的InitInstance成员函数(TEST.CPP)完成应用程序的初始化工作。
(4)调用相应成员函数完成窗口类的设计、注册、创建窗口、显示窗口,刷新窗口。
(5)在AfxWinMain函数中调用CWinThread:
Run()函数实现消息循环。
在循环中调用PumpMessage函数完成消息的派分。
利用消息映射机制找到响应函数处理消息,直到接收到WM_QUIT消息,结束循环。
2.MFC消息类型
(1)标准Windows消息:
所有以WM_为前缀的消息标识都是标准的Windows消息(WM_COMMAND除外),一般由窗口类和视图类进行处理。
(2)控件通知消息:
MFC应用程序处理控件消息的方法和Windows消息相同,一般由窗口类或视图类处理。
(3)命令消息:
是指与用户交互命令有关的消息,是由用户界面对象发送的WM_COMMAND消息,其中用户界面对象是指菜单、工具栏和快捷键等。
3.MFC常见类
(1)CWinApp应用程序类:
MFC中的主应用程序类,用于