300 likes | 465 Views
C 语言程序设计 第 12 章 C++ 程序设计基础. 第 12 章 C++ 程序设计基础. 主要内容 12.1 面向对象程序设计概述 12.2 从 C 到 C++ 12.3 C++ 的非面向对象知识. 12.1 面向对象程序设计概述. 12.1.1 面向对象程序设计的基本概念 12.1.2 面向对象程序设计的特点 12.1.3 类和对象的作用 12.1.4 面向对象的软件开发. 12.1.1 面向对象程序设计的基本概念. 1 .对象
E N D
C语言程序设计 第12章 C++程序设计基础
第12章C++程序设计基础 主要内容 • 12.1 面向对象程序设计概述 • 12.2 从C到C++ • 12.3 C++的非面向对象知识
12.1 面向对象程序设计概述 • 12.1.1 面向对象程序设计的基本概念 • 12.1.2 面向对象程序设计的特点 • 12.1.3 类和对象的作用 • 12.1.4 面向对象的软件开发
12.1.1 面向对象程序设计的基本概念 1.对象 对象是构成系统的基本单位。任何一个对象都应当具有这两个要素,即属性( attribute)和行为(behavior),它能根据外界给的信息进行相应的操作。一个对象往往是由一组属性和一组行为构成的。 在C++中,每个对象都是由数据和函数(即操作代码)这两部分组成的。数据体现了 “属性”;函数是用来对数据进行操作的,以便实现某些功能。 2.封装与信息隐蔽 所谓“封装”,指两方面的含义:一是将有关的数据和操作代码封装在一个对象中,形成一个基本单位,各个对象之间相对独立,互不干扰;二是将对象中某些部分对外隐蔽,即隐蔽其内部细节,只留下少量接口,以便与外界联系,接收外界的消息。这种对外界隐蔽的做法称为信息隐蔽(imformation hiding)。信息隐蔽还有利于数据安全,防止无关的人了解和修改数据。 C++的对象中的函数名就是对象的对外接口,外界可以通过函数名来调用这些函数来实现某些行为。
12.1.1 面向对象程序设计的基本概念 3.抽象 抽象的作用是表示同一类事物的本质。C和C++中的数据类型就是对一批具体的数的抽象。例如,“整型数据”是对所有整数的抽象。类是对象的抽象,而对象则是类的特例,或者说对象是类的具体表现形式。 4.继承与重用 如果在软件开发中已经建立了一个名为A的“类”,又想另外建立一个名为B的“类”,而后者与前者内容基本相同,只是在前者的基础上增加一些属性和行为,显然不必再从头设计一个新类,而只需在类A的基础上增加一些新内容即可。这就是面向对象程序设计中的继承机制。利用继承可以简化程序设计的步骤。 C++提供了继承机制,采用继承的方法可以很方便地利用一个已有的类建立一个新的类,这就可以重用已有软件中的一部分甚至大部分,大大节省了编程工作量。这就是常说的“软件重用”(software reusability)的思想,不仅可以利用自己过去所建立的类,而且可以利用别人使用的类或存放在类库中的类,对这些类作适当加工即可使用,大大缩短了软件开发周期,对于大型软件的开发具有重要意义。 5.多态性 由继承而产生的相关的不同的类,其对象对同一消息会作出不同的响应。多态性是面向对象程序设计的一个重要特征,能增加程序的灵活性。
12.1.2面向对象程序设计的特点 • 传统的面向过程程序设计是围绕功能进行的,用一个函数实现一个功能。所有的数据都可以公用,一个函数可以使用任何一组数据,而一组数据又能被多个函数所使用。程序设计者必须考虑每一个细节,什么时候对什么数据进行操作。当程序规模较大、数据很多、操作种类繁多时,程序设计者往往感到难以应付。 • 面向对象程序设计采取的是另外一种思路,它面对的是一个个对象。实际上,每一组数据都是有特定的用途的,是某种操作的对象。也就是说,一组操作调用一组数据。 • 面向对象程序设计者的任务包括两个方面:一是设计所需的各种类和对象,即决定把哪些数据和操作封装在一起;二是考虑怎样向有关对象发送消息,以完成所需的任务
12.1.3 类和对象的作用 • 类是C++中十分重要的概念,它是实现面向对象程序设计的基础。C++对C的改进,最重要的就是增加了“类”这样一种类型。类是所有面向对象的语言的共同特征,所有而向对象的语言都提供了这种类型。如果一种计算机语言中不包含类,它就不能称为面向对象的语言。一个有一定规模的C++程序是由许多类所构成的。可以说,类是C++的灵魂,如果不真正掌握类,就不能真正掌握C++。 • 基于对象就是基于类。与面向过程的程序不同,基于对象的程序是以类和对象为基础的,程序的操作是围绕对象进行的。在此基础上利用了继承机制和多态性,就成为面向对象的程序设计。
12.1.4 面向对象的软件开发 1.面向对象分析(object oriented analysis,OOA ) 软件工程中的系统分析阶段,系统分析员要和用户结合在一起,对用户的需求作出精确的分析和明确的描述,从宏观的角度概括出系统应该做什么。面向对象的分析,要按照而向对象的概念和方法,在对任务的分析中,针对客观存在的事物和事物之间的关系,归纳出有关的对象以及对象之间的联系,并将具有相同属性和行为的对象用一个类(Class)来表示。建立一个能反映真实工作情况的需求模型。在这个阶段所形成的模型是比较粗略的。
12.1.4 面向对象的软件开发 2.面向对象设计(object oriented design,OOD) 根据面向对象分析阶段形成的需求模型,对每一部分分别进行具体的设计。首先是进行类的设计,类的设计可能包含多个层次;然后以这些类为基础,提出程序设计的思路和方法,包括对算法的设计。在设计阶段,并不牵涉某一种具体的计算机语言,而是用一种更通用的描述工具来描述。
12.1.4 面向对象的软件开发 3.面向对象编程(object oriented programming,OOP) 选用某种面向对象的计算机语言,如C++,根据面向对象设计的结果编制程序。面向过程的语言,如C语言是无法实现面向对象设计的要求的。 4.面向对象测试(object oriented test,OOT ) 在编制好程序交给用户使用前,必须对程序进行严格的测试。测试的目的是发现程序中的错误并改正它。面向对象测试是用面向对象的方法进行测试,以类作为测试的基本单元。
12.1.4 面向对象的软件开发 5.面向对象维护(object oriented soft maintenance,OOSM) 正如对任何产品都需要进行售后服务和维护一样,软件在使用中也会出现一些问题,或者软件商想改进软件的性能,这就需要修改程序。由于使用了面向对象的方法开发程序,使得程序的维护比较容易了。因为对象的封装性,修改一个对象对其他对象影响很小。利用面向对象的方法维护程序,大大提高了软件维护的效率。
12.2 从C到C++ C++与C的不同之处主要表现在如下两个方面: • 第一个方面是对C语言在面向过程设计中的不足进行了改进,扩充了C语言的功能,提高了程序设计的灵活性。 • C++与C的不同之处第二个方面是C++引入了面向对象技术,是一种面向对象的程序设计语言,而C是一种面向过程的程序设计语言,它与面向过程的程序设计在思想和方法上有本质的区别。
12.3 C++的非面向对象知识 • 12.3.1 简单的C++程序 • 12.3.2 C++的输入和输出 • 12.3.3 内联函数 • 12.3.4 函数重载 • 12.3.5 函数的参数的默认值 • 12.3.6 变量的引用
12.3.1 简单的C++程序 例12-1 显示字符串程序。 // 程序e12-1.cpp #include <iostream> void main() { cout<<"This is a C++ program. "<<endl;// 输出字符串 }
12.3.1 简单的C++程序 例12-3 用自定义函数的方法来实现例12-2的问题。 // 程序e12-3.cpp #include <iostream.h> double add(double x,double y) { return x+y; } void main() { double a,b; cout<<"Enter a,b: "; cin>>a>>b; double c=add(a,b); cout<<"a+b="<<c<<endl; }
12.3.1 简单的C++程序 例12-2 从键盘上输入两个实数,求它们的和。 // 程序e12-2.cpp #include <iostream> void main() { double x,y; cout<<"Enter x,y: "; // 显示提示信息 cin>>x>>y; // 从键盘输入x和y double z=x+y; cout<<x<<"+"<<y<<"="<<z<<endl; }
12.3.2 C++的输入和输出 1.用cout输出 用cout和“<<”可以输出任何类型的数据,其一般用法如下: cout<<表达式1<<表达式2<<表达式2<<……<<表达式n; 其功能是依次输出各个表达式。其中的“<<”称为插入运算符,结合方向自左向右,作用是将其后的表达式插入到输出流中。 2.用cin输入 cin和“>>”可以实现任何类型数据的输入,其一般用法如下: cin>>变量1>>变量2>>……>>变量n; 其功能是通过键盘依次输入各变量的值。其中的“>>”称为提取运算符,通过它从键盘取得数据后再送到输入流cin中,最后送往内存。使用cin和“>>”输入数据时同样不需要指定数据类型。
12.3.2 C++的输入和输出 例12-4 用cin输入数据,然后用cout将输入的数据输出。 #include <iostream.h> void main() { char name[9]; int score; cout<<"Input name:" ; cin>>name; cout<<"Input score:"; cin>>score; cout<<"Name: "<<name<<" Score: "<<score<<endl; }
12.3.3内联函数 • 内联函数的定义 inline 函数返回值类型 函数名(函数参数表) { 函数体 } • 在使用内联函数时需要注意 ⑴ 内联函数内不允许出现循环语句和开关语句,如果一个内联函数包含了这些语句,则系统将该内联函数视为普通函数。 ⑵ 内联函数一般用于函数规模较小的情况,若把函数体较大的函数定义为内联函数,当函数调用较多时,将大大增加程序的目标代码长度。
12.3.3内联函数 例12-5 计算(a+b)3+(a-b)3。 #include <iostream.h> int cube(int); // 函数声明 void main() { int a,b; cout<<"input a&b: "; cin>>a>>b; cout<<cube(a+b)+cube(a-b)<<endl; // 输出结果 } inline cube(int x) // 定义求x的三次方的内联函数 { return x*x*x; }
12.3.4函数重载 • 所谓函数重载就是指同一个函数名对应着多个不同的函数实现。 • 函数重载除了函数功能上比较接近外,相关函数在定义时总要有些差别,否则函数的重载将演变成函数的重复定义,这在C++中是不允许的。各函数重载之间的差别主要表现在函数返回值的类型、函数参数的类型、函数参数的个数、函数参数的顺序等方面的差异,系统根据这些差异来选择相应的函数。需要注意的是,函数重载仅仅靠函数不同的返回值类型是不够的,在进行重载函数的定义时,保证函数名相同的前提下要将上述的那些区别明显地表现出来。
12.3.4函数重载 例12-6 函数重载应用示例。 #include <iostream.h> int max(int,int),max(int,int,int),max(int,int,int,int); void main() { cout<<"Max of 2 integers is "<<max(25,26)<<endl; cout<<"Max of 3 integers is "<<max(25,27,26)<<endl; cout<<"Max of 4 integers is "<<max(25,26,28,27)<<endl; } int max(int a,int b) { return a>b?a:b; } int max(int a,int b,int c) { int t=max(a,b); return max(t,c); } int max(int a,int b,int c,int d) { int t1=max(a,b); int t2=max(c,d); return max(t1,t2); }
12.3.5函数的参数的默认值 • C++允许在定义函数或说明函数时设置函数的形参值,这些值称为函数参数的默认值。在进行函数调用时,若不给出对应的实参值,则使用参数的默认值。C++通过设置函数参数的默认值,使函数调用更加方便,同时也使程序设计更灵活。 • 例:int add(int a, int b=5, int c=8);
12.3.5函数的参数的默认值 • 在C++中,使用函数参数默认值时需要注意以下几点: ⑴ C++允许为形参表中的所有参数设置默认值,也允许为部分参数设置默认值。设置参数的默认值要从形参表中最右端的参数开始,设置默认值要从右向左连续进行,在指定了默认值的参数右边不允许再出现尚未指定默认值的参数。 ⑵ 当函数被调用时,如果指定了具体的实参表,则调用时的实参值将取代原来参数的默认值;如果没有给定实参值,则使用参数的默认值。 ⑶ 缺省参数既可以在函数原型说明中设置,也可以在函数定义时设置,但必须保证要在函数调用之前进行设置。 ⑷ 在给函数参数设置默认值时,被指定的默认值可以是常数,也可以是表达式。
12.3.5函数的参数的默认值 例12-7 使用默认值的函数示例。 #include <iostream.h> void fun(int a=1,int b=2,int c=3) { cout<<"a="<<a<<", b="<<b<<", c"<<c<<endl; } void main() { fun(); // 三个实参全部使用默认值 fun(4); // 后两个实参使用默认值 fun(4,5); // 第三个实参使用默认值 fun(4,5,6); // 不使用默认值 }
12.3.6 变量的引用 1.引用的概念 引用就是某个变量的别名。引用通过运算符&定义,一般形式如下: 类型名 &引用名=变量名; 从一般格式可见,在为某个变量建立引用时,要求对引用进行初始化,这时引用和用来初始化的那个变量便“捆绑”在一起,对引用的改变也就是对变量的改变。 例如: int a; int &ra=a;
12.3.6 变量的引用 例12-9 变量的引用示例。 #include <iostream.h> void main() { int val(2000); int &refv=val; //refv是val的引用 cout<<"val: "<<val<<", refv: "<<refv<<endl; val+=4; cout<<"val: "<<val<<", refv: "<<refv<<endl; refv+=4; cout<<"val: "<<val<<", refv: "<<refv<<endl; }
12.3.6 变量的引用 • 2.引用作函数参数 • 在定义函数时形参可以出现引用。引用充当函数参数时传递的是地址,与指针变量作函数参数所起的作用相同。一般地,引用作函数参数时程序的可读性要好些,这是因为当引用作函数形参时,函数发生调用时的实参可以用变量名,这与传统意义上的传值调用相似。与之相反,如果是指针变量用作函数参数,则函数调用时实参必须是地址。 • 其实,在C++中,程序设计人员更为关心的只是函数调用的形式,至于被调用函数的定义形式就不是那么关心了,只要调用函数的可读性好就可以满足用户的要求,因此C++中充当函数参数时引用比指针有更广泛的应用。如下是两个例子,希望读者通过示例比较,学会使用引用作函数参数的方法。
12.3.6 变量的引用 例12-10 用指针变量作函数参数,定义一个函数swap()来交换两个int变量的值。 void swap(int *pl,int *p2) // 形参为指针变量 { int temp; temp=*p1; *p1=*p2; *p2=temp; } void main() { int i=4,j=5; cout<<"before exchange: i="<<i<<", j="<<j<<endl; swap(&i,&j); // 函数调用时实参为变量的地址 cout<<"after exchange: i="<< i<<", j="<< j<<endl; }
本章小结 1.与面向过程的程序设计方法相比,面向对象技术引入了许多性概念,如对象、封装、消息、继承与重用、类等。 2.cout和cin是C++中更为常用的输出和输入方法,它们在用于数据的输出和输入时,既不用指明数据的类型,也不用定义数据的格式,使用时比printf()和scanf()更方便和灵活。 3.内联函数解决了程序中频繁调用小函数的效率问题,一个使用了内联函数的源程序被编译时,C++编译系统会将程序中出现的调用内联函数的表达式用内联函数的函数体来替换。 4.函数重载是C++的一项重要技术,它允许在一个程序中把功能相近的的函数定义为同名函数,编译系统根据函数调用自动选用最为匹配的函数。 5.C++允许设置函数的参数的默认值。C++通过设置函数参数的默认值,使函数调用更加方便,同时也使程序设计更灵活。 6.变量的引用就是变量的别名,变量和它的引用是捆绑在一起的。变量的引用可以作为函数的参数,当引用作函数形参时,实参将直接使用变量的名字,但实际传送的是变量的地址。