1、数据结构与算法,第1章 面向对象程序设计基础,本章主要内容: C+基本特征 面向对象程序设计三个基本技术:类、继承和多态性,1.1 C+基本特征,1.1.1 重载 1函数重载在C+中,只要函数的参数个数或者参数类型不同,就允许在同一作用域中以出现同名函数。,例1-1 编写同名max( )函数。 int max(int a, int b); / 求2个整数中的最大者 float max(float a, float b); / 求2个实数中的最大者 char max(char a, char b); / 求2个字符中的最大者,允许一个运算符用于不同场合、有不同的含义,这就叫做运算符的“重载”。例
2、1-2 重载结构体的“”运算符。,2运算符重载,1缺省参数函数C+允许实参个数与形参个数不相同。使用办法:在中对一个或几个形参指定缺省值(或默认值)。,1.1.2 缺省参数函数与内置函数,如果有的函数需要频繁调用,为提高效率,C+提供一种方法可将这种函数的代码在编译时嵌入到主调函数中。这种嵌入到主调函数中的函数称为内置函数(或内联函数)。,2内置函数,引用(reference)是C+的一种新的变量类型,是对C的一个重要扩充。要注意引用与指针的取地址符的区别。,1.1.3 引用及其使用,引用是给对象起一个别名。引用的说明符如下: 类型名 ,1独立引用引用并不另开辟内存单元。例1-3 引用和变量的
3、关系。 2引用作为参数传递在C语言中,函数的参数传递有以下两种情况:,(1)值传送。这时变量名作为实参传给形参的是变量的值。因此,传送是单向的,在执行函数期间形参值发生变化并不传回给实参。例1-4 值传送。,(2)地址传送。这时传送变量的指针。因此,传送是双向的,形参和实参共享一个变量单元。C+提供了第三种传递数据的方法,即传递变量的别名。例1-5 使用引用作参数,实现两个整型变量值的互换。,使用别名的传递方式和使用指针作形参有几乎完全相同的作用。因此在这种情况下,C+中常常用引用变量来代替指针。,若有以引用作为返回类型的函数如下: int A6; int 例1-6 引用作为函数返回类型的使用
4、。,3引用作为返回类型,引用与指针有明显的区别: (1)引用在创建时必须被初始化;而指针则可以在任何时候初始化。 (2)不能有NULL引用,引用必须与合法的存储单元相关联;而指针则可以是NULL,表示空指针。,(3)一旦引用被初始化,就不能改变引用的关系;但是指针随时可以改变所指向的对象。,1运算符new new的语法如下: 指针名 = new 类型名();,1.1.4 动态内存分配,例如:/ 开辟一个存放整数的空间并返回指向该值的指针存放在pint中 int *pint; pint = new int;/ 开辟一个存放整数的空间并指定整数初值为20,返回指针存放在pint中 int *pin
5、t; pint = new int(20);,/ 开辟存放字符数组的空间并返回指向该数组的指针存放在ps中 char *ps; ps = new char10;/ 开辟存放整型数组的空间并返回指向该数组的指针存放在pa中 int *pa = new int5;,/ 开辟内存存放double型的值并返回指向该值的指针 double *pi = new double(3.14159);,运算符delete用来清除由new分配的对象,释放指针指向的内存空间。其语法如下: delete 指针名;例1-7 开辟存放一维数组的堆空间。例1-8 开辟存放二维数组的堆空间。,2运算符delete,1.2 类和
6、对象,在C+中,声明“类”数据类型,可使用如下语法:class 类名private:私有数据成员和成员函数public:公用数据成员和成员函数;,例1-9 建立日期类date。 C+中一个对象可以声明如下:类名 对象名; 而调用一个对象的成员函数的语法是:对象名.成员函数名(实参表);,在C+中,在类外定义成员函数的语法如下: 函数类型名 类名:成员函数名(形参表) 局部变量声明与执行代码 例1-10 在类外定义成员函数。,1.2.2 在类外定义成员函数,在定义一个类之后,如果需要使用该类的多个对象,可以声明类数组。其语法与普通数组变量类似。例1-11 建立青年类young。例1-12 青年类
7、及其输入类。,1.2.3 类数组、类指针与函数的类参数,this是C+的一个关键字。在C+中,对象的每个成员都有一个指向该对象的指针,这就是this指针。this指针是一个常量指针,它不能被声明、修改和赋值。例1-13 this指针的使用。,1.2.4 this指针,1.3 构造函数与析构函数,1.3.1 构造函数利用自定义的构造函数来给对象赋初始值。构造函数也称为构造器,其作用与其他函数不同,它不需要用户调用它,而是在创建对象时由系统自动执行它。在C+中,构造函数是由用户定义的,它必须与类名同名,以便系统识别它作为构造函数。,例1-14 实现具有构造函数的青年类。注意:构造函数是一种特殊的函
8、数。它不需要用户调用,而是在定义一个对象时由系统自动执行,并且只能执行一次。构造函数一般声明在public部分,它没有返回值,也不能加void类型声明。,析构函数也称为析构器,其作用与构造器相反,常常用来做“清理善后工作”。当一个对象使用完毕时,系统自动执行析构函数。例如,在建立对象时,如果用new运算符开辟了一片内存空间,应在退出前在析构函数中用delete运算符予以释放。,1.3.2 析构函数,C+中,析构函数名也应与类名相同。只是在函数名前面加一个波浪号,例如,date( ),以区别于构造函数date( )。每一个类中只能有一个析构函数,不能重载。如果用户没有编写析构函数,编译系统会自动
9、生成一个缺省的析构函数,所以许多简单的类中没有用显式的析构函数。,例1-15 实现具有构造函数和析构函数的日期类。注意:析构函数也是一种特殊的函数。析构函数一般声明在public部分,它同样没有返回值,也不能加void类型声明。当一个对象使用完毕时,系统自动执行析构函数。,1.4 继承与派生,继承机制允许在已有类的基础上进行再开发,就象搭积木一样,将已有类的程序代码(含数据成员和成员函数)视为一个现成的对象,加上一些新建的对象来生成具有某种特定功能的新对象。,C+继承机制对继承而来的类可以做下列更新: (1)允许加入新的数据成员; (2)允许加入新的成员函数; (3)允许修改既有的方法。,继承
10、性使得用户不必修改已有类,便可在其基础上定义新类,这无疑是程序设计划时代的创造。它使利用面向对象技术编写的软件具有良好的可扩充性和易修改性等特征,因此继承机制是面向对象编程语言的基本要素之一。,所谓继承就是在一个已有类的基础上建立一个新类。已有类称为“基类”(或父类);新建类称为“派生类”(或子类)。,1.4.1 建立派生类,在派生类中可以继承基类中的数据和操作,可以添加新的数据和操作,并且可以去掉(覆盖)不需要的操作。例1-16 实现青年类的公用派生类学生类。,在C+中,当声明一个派生类时,凡将基类的引用权限指定为public的,称该类为公用派生类;凡将基类的引用权限指定为private的,
11、称该类为私有派生类。,1.4.2 公用派生类与私有派生类,在公用派生类中,基类的公用成员和保护成员仍然成为派生类的公用成员和保护成员,而基类的私有成员不能在类外引用,因此成为“不可访问成员”。,在私有派生类中,基类的公用成员和保护成员将成为派生类的私有成员,而基类的私有成员同样成为“不可访问成员”。综上所述,有下面派生类继承关系表,如表1-1所示:,表1-1 派生类继承关系表,前面已接触过“保护(protected)”这一术语。它和private、public一样是用来声明成员的引用权限的。,1.4.3 保护成员,在protected部分内声明的成员称为保护成员,保护成员不能被外界引用(和pr
12、ivate部分的成员类似),但它可以被派生类的成员函数引用。例1-17 声明保护成员。,C+提供一种辅助手段,允许外部的类或函数去访问一个类的私有数据。这种类或函数称为被访问类的友元类或函数。在类的接口中对友元进行声明,只需先写出friend,然后再写出友元的名称。,1.4.4 友元函数与友元类,根据数据隐藏原则,类的数据成员一般设计为私有成员,类的私有数据就象一个黑匣子。其内容只能通过类的成员函数或者友元进行访问。下面将通过例子来说明友元函数的定义和使用。例1-18 友元函数的声明和使用。,1友元函数,如果将一个已有的类设计为另一个新类的一个友元,则新类中的所有成员函数都被作为已有类的友元函
13、数。 这时,必须在已有类中添加其友元类的声明。下面将通过例子来说明友元类的定义和使用。,2友元类,例1-20 友元类的定义。使用友元机制的重要性在于使用友元函数可以提高编程效率,但是使用友元却破坏了类的封装性和隐藏性,所以一般情况下要根据效率和类的封装性等因素综合来考虑友元的使用。,1.5 C+模板,C+与C相比有重大的改进。它将C中的数据结构进行了扩展,使得它不但能包含数据对象,还能包含成员函数。C+中的类可以更好地将一些相关的数据和处理这些数据的操作封装在一起。,在C+的最新发展中,新增了模板(template)这个特性。通过使用模板,可以提供更好的代码重用机会。,“模板”顾名思义,就是函
14、数和类的“模具”,它是指把函数和类的成员中的类型参数化。C+中模板分为函数模板和类模板。这一节的主要任务是学会书写和使用函数模板和类模板。,使用模板就是把数据类型本身作为一个参数,定义模板函数的格式如下: template 返回值类型 模板函数名( 参数表 ) 函数体 ,1.5.1 函数模板,其中template是关键字,表明模板定义;为模板参数表,表示数据类型的参数。参数T可以用任何标识符代替,为了提高程序可读性,建议还是使用T。,例如,交换函数的函数模板定义如下: template void swap(T ,这里定义的模板函数的含义是:无论模板参数T的对象是int型、float型、char型或者其他类型,都可以通过这个模板函数来实现两个变量值的交换。例1-21 函数模板的使用。,类似于函数模板,类模板就是将类的成员的数据类型参数化,即允许用户为类定义提供一个“模具”。,1.5.2 类模板,定义类模板的格式如下: template class 类模板名 成员定义 其中template和的含义与函数模板相同,这里不再作解释。,例1-22 类模板的使用。利用类模板建立通用类Myclass。Myclass类的数据成员是:姓名和三门课程的成绩;该类有两个成员函数:求平均分的函数和显示信息的函数并且要求成绩可以是整型的或实型的。,