C++ 程序设计 第2章 面向对象的基本概念
第2章 面向对象的基本概念
1 结构化程序设计
1.1 了解传统的结构化程序设计的基本方法及其局限性
基本方法
结构化程序设计也称为面向过程的设计方法,强调数据结构和程序结构,注重代码的易读性,可靠性及可维护性
采用自顶向下,逐步求精及模块化的思想,将复杂的大问题层层分解为许多简单的小问题。
三种基本机构,顺序,选择,循环
基本思想,数据结构+算法=程序,数据结构和变量相对应,算法和函数相对应。
局限性
程序在代码规模庞大时,变得难以理解,难以扩充,难以查错和难以复用。
1.2 掌握一般意义下面向过程程序设计的特点
结构化程序设计采用自顶向下、逐步求精的设计方法,各个模块通过“顺序、选择、循环”的控制结构进行连接,并且只有一个入口、一个出口。
自顶向下,逐步细化,模块化
2 面向对象程序设计的概念和特点
2.1 初步理解面向对象程序设计的思想,了解类及对象的核心概念,掌握C++面向对象程序设计的概念和特点,并与结构化程序设计进行对比
面向对象程序设计的思想
继承了机构化程序设计方法的优点,同时又比较有效地改善了结构化程序设计的不足。
就是使分析,设计和实现一个系统的方法尽可能地接近人们认识一个系统的方法,通常包括3个方面,面向对象的分析,面向对象的设计和面向对象的程序设计。
面向对象技术把问题看成是相互作用的事物的集合,也就是对象的集合,对象具有两个特性,一是状态,二是行为,状态是指对象本身得信息,也称为属性。行为是对对象的操作。
类及对象的核心概念
通过对事物的抽象找出同一类对象的共同属性(静态特征)和行为(动态特征),从而得到类的概念
对象是类的具象,类是对象的一个抽象。在面向对象技术中,属性表现为数据,用属性值来描述对象的状态,而把对对象的操作定义为函数,这样,对象就是数据加函数。
类是面向对象程序设计方法中的程序主体,类中的大多数数据只能用本类的方法处理,以保障程序模块的独立性及对象的安全性。
类通常通过简单的公共对外接口与外界联系。
C++面向对象设计的概念和特点,并于结构化程序设计进行对比
抽象,封装,继承,多态
C++使用对象名,属性和操作三要素来描述对象,通过用户定义的类来支持数据封装和信息隐藏,多态性仅用于通过继承而相关联的引用或指针,因此通过继承而相关联的类型称为多态类型。
结构化的程序设计语言对此没有特殊支持
2.2 理解抽象与封装的含义
抽象:将同一类事物的共同特点概括出来,这个过程就叫做抽象。
封装:每个给定类的对象包含了这个类所规定的若干私有成员,公有成员及保护成员。封装将对象属性和操作结合在一起,构成独立的单元。体现的特点是将对象的属性及实现细节隐藏起来,只给出如何使用的信息。有了封装机制,对象内部的实现细节受到保护,公开的信息成为与外界交互的接口。
继承和复用:在C++现有类的基础上可以声明新的类,将一个已知类中的数据和函数保留,并加上自己特殊的数据和函数,从而构成一个新类。原来的类是基类,也成为父类或超类。新类是派生类,也称为子类。继承体现的是一种层次关系。
动态绑定:通过基类的引用或指针调用虚函数时,发生动态绑定。引用既可以指向基类对象也可以指向派生类对象。用引用调用的虚函数在运行时确定,被调用的函数是引用所指对象的实际对象所定义的。使用这些类的程序也不必去区分函数是在基类还是在派生类中定义的,由此得到多态的定义。意思是许多形态。
在一个类或多个类中,可以让多个方法使用同一个名字,从而具有多态性,这是通过函数重载及运算符重载实现的多态。
3 类的初步知识
3.1 理解类的概念
C++中,基本数据类型的变量也是对象。类以数据为中心,把相关的一批函数组成为一体。
类定义的一般格式
class 类名
{
访问范围说明符:
成员变量1
成员变量2
...
成员函数1
成员函数2
...
访问范围说明符:
更多成员变量
更多成员函数
...
};
类是具有唯一标识符的实体,类名不能和重复,类定义以 ; 结束,大括号中的部分称为类体。
访问限定符:public 公有,private 私有,protected 保护,在类定义中可以以任意的次序出现任意多次。
3.2 掌握成员变量,成员函数的概念
成员变量,是类中的一类成员,个数不限,也称为数据成员。同样的,成员函数也是是类中的一类成员,个数不限
成员变量和成员函数出现的先后次序没有限制,一个类的成员函数之间可以互相调用,成员函数可以重载,也可以设定参数的默认值
成员变量和成员函数的名字必须是合法的标识符,它们的声明必须在类体内完成。
类中不包含任何成员变量和成员函数,这样的类称为空类。
定义类时系统并不为类分配存储空间,而只是把类看作是一种模板或样板,在C++98中,类中声明的任何成员不能使用 auto extern register关键字修饰
类中的成员变量不能在声明时进行初始化,不能在类体声明成员变量的同时给它赋初值,类的静态成员变量除外。
设置函数,获取函数,成员变量私有,类外不可访问。
类中的成员按功能划分,包括成员变量和成员函数,按访问权限划分,包括公有成员,私有成员,保护成员。
C++中还可以定义不是任何类的成员的函数,称为全局函数。
成员函数既可以在类体内定义,也可以在类体外定义。如果成员函数定义在类体内部,则默认是内联函数。也可以在类体内声明函数,并加上inline关键字,然后在类体外给出函数定义,这样的成员函数也是内联函数。
成员函数定义在类体外,则类体内必须要有函数原型,类体外函数定义的前面必须用 类名:: 来限定
返回值类型 类名::成员函数名(参数列表){
成员函数的函数体
}
类名是成员函数所属类的名字,符号::是类作用域运算符,表明它后面的成员函数是属于类名标识的这个类的。
4 类的示例程序剖析
4.1 了解程序结构
一个完整的C++程序包括以下几部分
一个主函数,可以调用其他函数,但不能被调用,也称为主程序
用户定义的任意多个的类及全局函数
全局说明。在所有函数和类定义之外的变量说明及函数原型
注释
头文件
从逻辑关系看,典型的C++程序的结构包括类的定义,类中成员函数的实现及主函数main
如果多个cpp文件包含同一个类,可以将类的定义写在一个头文件中,然后再各个cpp文件中包含该头文件。类的非内联成员函数的函数体只能出现在某一个cpp文件中,不能放在头文件中被多个cpp文件包含,否则链接时会发生重复定义的错误。
类的内联成员函数的函数体最好写在头文件中,这样编译器再处理内联函数的调用语句时,就能在本文件包含的头文件中找到内联函数的代码,并将这些代码插入调用语句处。内联成员函数放在头文件中被多个cpp文件包括,不会导致重复定义的错误
4.2 掌握成员变量及成员函数的一般定义格式
成员变量一般定义为私有访问权限,这样的成员仅能再本类内访问
成员函数定义格式
返回值类型 类名::成员函数名(参数表){
函数体
}
成员函数并非每个对象各自存有一份。成员函数和普通函数一阿姨那个,在内存中只有一份,它可以作用于不同的对象,为类中各对象共享。
4.3 熟练掌握定义类的基本方法
具有类类型的变量称为对象,完整的定义了类之后,就可以创建对象了。创建对象也称为声明,定义或生成对象。
定义了类数据类型只是告诉编译系统该数据类型的结构或框架,并没有分配内存。类只是一个样板,根据这个样板,可以在内存中开辟出同样结构的实例,所以说对象是类的实例。
5 访问对象的成员
5.1 理解对象的概念,能够声明类的对象
定义一个普通对象
基本格式1
类名 对象名;
类名 对象名(参数);
类名 对象名 = 类名(参数);
// 扩展
类名 对象名1,对象名2,对象名3,...;
类名 对象名1(参数1),对象名2(参数2),对象名3(参数3),...;
此处,对象名的命名规则和普通变量相同,必须是一个符合要求的标识符。创建对象时是否带有参数,要依赖于类中构造函数的形式。
创建对象后,C++会为它分配相应的空间,用来存储对象所有的成员变量,而类中定义的成员函数则被分配到存储空间中的一个公用区域,由该类的所有对象共享
基本格式2
类名 *对象指针名 = new 类名;
类名 *对象指针名 = new 类名();
类名 *对象指针名 = new 类名(参数);
用new创建对象时返回的是一个对象指针,这个指针指向本类刚创建的这个对象。C++分配给指针的仅仅是存储指针值的空间,而对象所占用的空间分配在堆上。使用new创建的对象,必须用delete销毁
与基本类型一样,还可以声明对象的引用,对象的指针及对象的数组。
类名 &对象引用名 = 对象;
类名 &对象指针名 = 对象的地址;
类名 对象数组名[数组大小];
5.2 掌握通过对象访问类成员的方法,掌握使用指针,引用访问类成员的方法
对象访问成员变量的一般格式是 对象名.成员变量
对象访问成员函数的一般格式是 对象名.成员函数名(参数表);
使用指针访问类成员,则点运算符换为箭头运算符 ->,指针 -> 成员名
使用引用访问类成员时仍使用点操作符 引用名.成员名
6 类成员的可访问范围
6.1 了解类定义中各个访问范围说明符的含义
public 公有的,使用它修饰的类的成员可以在程序的任何地方被访问
private 私有的,使用它修饰的类的成员仅能在本类内被访问
protected 保护的,它的作用介于public 与 private 之间,使用它修饰的类的成员能在本类内及子类中被访问
3种关键字出现的次数和先后次序没有限制,成员的可访问范围由它之前离它最近的那个访问范围说明符决定。如果某个成员前面没有访问范围说明符,则对于类来说,该成员默认是私有成员。
在默认情况下,类的所有成员都是私有的。
私有类型的成员在类外是不能访问的,通过公有函数访问的效率比直接访问的效率要低。为了权衡这两方面的因素,C++提供了友元访问方式。只有在类内和在友元函数内才可以访问私有成员
6.2 理解类成员的可访问范围
7 标识符的作用域与可见性
7.1 理解标识符的作用域与可见性,理解隐藏的含义
隐藏:就是强制对私有成员变量的访问一定要通过公有成员函数进行,这样做的好处是,如果以后修改了成员变量的类型等属性,只需要更改成员函数机可,否则,所有直接访问成员变量的语句都需要修改
隐藏有利于程序的修改,隐藏还可以避免对对象的不正确操作,在设计类的时候,应当尽可能隐藏使用者不需要知道的实现细节,只留下必要的接口,即一些成员函数来对对象进行操作,这样能避免类的使用者随意使用成员函数和成员变量而导致错误
C++标识符的作用域有函数原型作用域,局部作用域(块作用域),类作用域和命名空间作用域。
函数原型作用域是最小的作用域,作用域只在形参列表的左右括号之间,在程序的其他地方不能饮用这个标识符,因为函数声明中形参仅在形参列表中有效,所以,函数声明中往往不屑形参名,而仅写形参的类型。
局部作用域,使用相匹配的一对大括号括起来的一段程序成为块。作用域局限在块内的称为局部作用域。
类作用域,类可以被看成一组有名字的成员的集合。类的成员函数中如果没有相同声明同名的局部作用域标识符,那么在该函数内可以直接访问该标识符,类外,可以通过 . 和 -> 来访问成员变量,当然不能违反访问修饰符的限定。
命名空间作用域,具有命名空间作用域的变量也被称为全局变量
对于不同的作用域声明的标识符,可见性的一般原则如下:
- 标识符要声明在前,引用在后
- 在用一个作用域中,不能声明同名的标识符,在没有互相包含关系的不同作用域中声明的同名标识符,互不影响
- 如果存在两个或多个具有包含关系的作用域,外层声明了一个标识符,而内层没有再次声明同名标识符,那么外层标识符在内层仍然可见。如果在内层声明了同名标识符,则外层标识符在内层不可见,这时称内层标识符隐藏了外层同名标识符,这种机制称为隐藏规则
7.2 理解命名空间的含义与定义形式
命名空间,一个大型的程序通常由不同模块构成,不同的模块甚至有可能是由不同人员开发的,不同模块中的类和函数之间可能发生重名,这样就会引发错误,命名空间是为了消除同名引起的歧义
定义命名空间的一般格式
namespace 命名空间名{
命名空间内的各种声明(函数声明,类声明,……)
}
如果需要引用其他命名空间的标识符使用 命名空间名::标识符名
引用类名和函数名
命名空间名::类名 对象名
命名空间名::函数名(参数表)