C程序设计语言类_第1页
C程序设计语言类_第2页
C程序设计语言类_第3页
C程序设计语言类_第4页
C程序设计语言类_第5页
已阅读5页,还剩45页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

会计学1C程序设计语言类教材中强调了两种方法:结构化程序设计面向对象程序设计具体内容参看教材p95-96第1页/共50页二面向对象程序设计的基本特点面向对象软件开发方法是吸收了软件工程领域有益的概念和有效的方法而发展起来的一种软件开发方法。它集抽象性、封装性、继承性和多态性于一体,可以帮助人们开发出模块化、数据抽象程度高的,体现信息隐蔽、可复用、易修改、易扩充等特性的程序。在系统分析与设计中,抽象用来确定必要的信息系统需求,删除不必要的部分。为了突出重点,抽象有意地忽略信息系统的某些性质、属性或功能。抽象是一种突出重点、去掉细节的总结。例如:地图的抽象,根据抽象的层次,地图可分为国家地图、行政省或地区地图、城市地图、邮政代码地图等。参看教材p97第2页/共50页封装或信息隐蔽

封装或信息隐蔽指软件的组成部分(模块、子程序、方法等)应该互相独立,或者隐藏设计的细节。

在系统分析和设计中,系统分析员把问题域分解为小的封装单元,这些分析和设计决定最终成为软件模块,封装就是有利于灵活地局部修改和维护软件模块。第3页/共50页封装或信息隐蔽用于以下两种情况1、当人们只能使用或接触整个系统的某个子集时。例如:当开发一个信息系统时,开发小组成员受命开发系统的某个部分,不需接触其它成员开发的部分。所以,封装或信息隐蔽适合于团队开发。2.有意防止信息系统的某些部件注意或利用系统的其它部件。这涉及到封装的另外一个方面----分配责任。正如现实生活中一个人负有某种责任,信息系统中的一个部件也有自己的责任,比如自动取款机的付钞功能,系统其它部件则担任付钞以外的其它责任。注意:在传统方法中,封装通常局限于将功能和数据分开封装;而在面向对象的方法中,封装将功能和数据同时装入对象中。第4页/共50页继承

继承是表示相似性质的机制。正如一个人同时继承父母的外貌特点一样,信息系统组成成分也从有关部件继承某些特点。例如:右图显示了‘人’和‘教师’、‘学生’及‘管理者’之间的继承关系。

‘人’和‘教师’、‘学生’及‘管理者’之间是继承(父子)关系,‘教师’、‘学生’、‘管理者’之间是兄弟关系。‘人’的特点如姓名、性别、年龄等,为继承层次中所有子节点继承;有些特点则为子节点独有,如授课时间只对‘教师’适用,平均分数只对‘学生’适用,头衔只对‘管理者’适用。同样,一些‘人’能做的事也对‘教师’、‘学生’及‘管理者’适用,例如吃饭、睡觉等,同样,有些事则为子节点独有。注意:继承在层次中是自上而下单向进行的。管理者人学生教师第5页/共50页多态多态一般指具有多种形态的能力。如:水有三种形态,液体、气体和固体。在某种程度上,在车里观察交通灯的反应是多态的,当交通灯闪现不同颜色时,人的反应是不同的。又如打印程序可以打印字符、数字、图形和图像,打印程序由于知道如何打印图文,因而是多态的。第6页/共50页第二节面向对象的方法面向对象是一种软件开发方法,软件开发的目的是为了进行数据处理,所以程序中包含了数据以及对数据的操作代码。面向对象的编程解决问题的思路从对象(人、地方、事情等)角度入手,而不像传统方法与结构化方法一样从功能入手。面向对象的开发强调从问题域的概念到软件程序和界面的直接映射;心理学的研究也表明,把客观世界看成是许多对象更接近人类的自然思维方式。对象比函数更为稳定;软件需求的变动往往是功能相关的变动,而其功能的执行者----对象----通常不会有大的变动。另外,面向对象的开发也支持、鼓励软件工程实践中的信息隐藏、数据抽象和封装。在一个对象内部的修改被局部隔离。面向对象开发的软件易于修改、扩充和维护。第7页/共50页面向对象编程----基本概念在面向对象编程中,程序被看作是相互协作的对象集合,每个对象都是某个类的实例,所有的类构成一个通过继承关系相联系的层次结构。面向对象的语言常常具有以下特征:对象生成功能、消息传递机制、类和遗传机制。这些概念当然可以并且也已经在其他编程语言中单独出现,但只有在面向对象语言中,他们才共同出现,以一种独特的合作方式互相协作、互相补充。过程化编程模式:参数输入-----|代码|------结果输出为实现某个功能,参数被传入某个处理过程,最后传回计算结果。面向对象编程模式:界面------|对象数据结构和操作第8页/共50页OO编程中,功能是通过与对象的通讯获得的。对象可以被定义为一个封装了状态和行为的实体;或者说是数据结构(或属性)和操作。状态实际上是为执行行为而必须存于对象之中的数据、信息。对象的界面,也可称之为协议,是一组对象能够响应的消息的集合。

消息是对象通讯的方式,因而也是获得功能的方式。对象受到发给他的消息后,或者执行一个内部操作(有时成为方法或过程),或者再去调用其他对象的操作。所有对象都是类的实例。类是具有相同特点的对象的集合,或者也可以说,类是可用于产生对象的一个模版。对象响应一个消息而调用的方法,由接受该消息的对象自己决定。类可以以一种层次结构来安排。第9页/共50页第三节面向对象的标记参看教材p100-101第10页/共50页第四节类与对象一类和类定义对象和对象定义初始化问题静态成员小结第11页/共50页一类和类定义----1、类的声明类和对象是面向对象程序设计(OOP)的两个最基本概念。所谓对象就是客观事物在计算机中的抽象描述;类是对具有相似属性和行为的一组对象的统一描述。类的定义

C++的类是在结构体的基础上扩充而来的。类是把各种不同类型的数据(称为数据成员)和对数据的操作(成员函数)组织在一起而形成的用户自定义的数据类型。

C++中,类定义包括类说明和类实现两大部分。说明部分提供了对该类所有数据成员和成员函数的描述,而实现部分提供了所有成员函数的实现代码。第12页/共50页类定义的一般形式为:class类名{private:

数据成员或成员函数

protected:

数据成员或成员函数

public:

数据成员或成员函数};

//注意:此处分号不要少<各成员函数的实现代码>定义类时,当未指明成员是哪部分时,默认是属于private成员,但一般不要采用默认形式。第13页/共50页几点说明(1)大括号的部分是类的成员(数据成员和函数成员),它们分成三部分,分别由private、public、proctected三个关键字后跟冒号来指定。这三部分可以任何顺序出现,且在一个类的定义中,这三部分并非必须同时出现。(2)类的数据成员可以使任何数据类型;(3)类的数据成员允许使用存储类型static,但其它三种存储类型不能使用;(4)类中数据成员不允许使用表达式进行初始化;(5)类中数据成员与成员函数可用const修饰。(6)经常习惯地将类定义的说明部分或者整个定义部分(包含实现部分)放到一个头文件中。第14页/共50页如:下例中定义描述图书的类定义

classRecord{private://private成员

charbookname[20];//数据成员bookname,

//用于表示图书的名称

intnumber;//数据成员number,表示图书编号

public: //public成员

voidregist(char*a,intb);//成员函数regist,用于给

//各数据成员赋值

voidshow();//成员函数show,显示各数据成员的值

};第15页/共50页根据类的定义,可看出:类是实现封装的工具,所谓封装就是将类的成员按使用或存取的方式分类,有条件地限制对类成员的使用,而封装是通过public和private与成员函数实现的。private的成员构成类的内部状态,public的成员则构成与外界通信的接口,通过public的成员函数来使用private的数据成员,从而在C++中实现了封装。第16页/共50页2、类成员的访问控制从访问权限上来分,类的成员又分为:公有的(public)、私有的(private)和保护的(protected)三类。公有的成员用public来说明,公有部分往往是一些操作(即成员函数),它是提供给用户的接口功能。这部分成员可以在程序中引用。私有的成员用private来说明,私有部分通常是一些数据成员,这些成员是用来描述该类中的对象的属性的,用户是无法访问它们的,只有成员函数或经特殊说明的函数才可以引用它们,它们是被用来隐藏的部分。保护的成员用protected来说明,这种成员只有该类的派生类可以访问,其余的在这个类外不能访问。保护类(protected)将在以后介绍。

第17页/共50页Who可以直接访问Who不能直接访问目的与用途private本类Public成员函数、本类保护成员函数、类的友元对象数据成员一般放在私有部分,实现信息隐蔽。protected本类公有成员函数、本类派生类(公有和私有派生)成员函数本类对象、派生类对象便于子类访问的成员一般放在保护部分。public本类公有成员函数、派生类成员函数、公有派生类对象私有派生类对象成员函数一般放在公有部分,实现共享。类成员的访问权限表第18页/共50页返回类名:私有部分的成员保护部分的成员公有部分的成员对于一个无继承关系的单一类(独立类),其访问权限可参考下图:该类的对象第19页/共50页3、类成员函数的特性类的成员函数可以分为内联函数和外联函数。内联函数是指那些定义在类体内的成员函数,即该函数的函数体放在类体内。而说明在类体内,定义在类体外的成员函数叫外联函数。外联函数的函数体在类的实现部分。

引入内联函数的目的是为了解决程序中函数调用的效率问题。因为内联函数在调用时不是像一般函数那样要转去执行被调用函数的函数体,执行完成后再转回调用函数中,执行其后语句,而是在调用函数处用内联函数体的代码来替换,这样将会节省调用开销,提高运行速度。

第20页/共50页在程序编译时,编译器将程序中出现的内联函数的调用表达式用内联函数的函数体来进行替换。显然,这种做法不会产生转去转回的问题,但是由于在编译时将函数休中的代码被替代到程序中,因此会增加目标程序代码量,进而增加空间开销,而在时间代销上不象函数调用时那么大,可见它是以目标代码的增加为代价来换取时间的节省。内联函数的定义方法

内联函数的定义方法与一般函数一样,只是在函数定义的头前加上关键字inline即可。如:

inlineintadd_int(intx,inty,intz)

{

returnx+y+z;

}返回第21页/共50页二对象和对象定义----1、对象的创建类是抽象的概念,而对象是具体的,类只是一种数据类型,而对象是属于该类(数据类型)的一个变量,占用了各自的存储单元,每个对象各自具有了该类的一套数据成员(静态成员除外),而所有成员函数是所有对象共有的。每个对象的函数成员都通过指针指向同一个代码空间。(参看教材p124图)对象的定义格式:

(1)class类名

{……}对象1,对象2,…,对象n;(2)类名对象1,对象2,…,对象n;(3)类名对象1(参数表),…,对象n(参数表);

如:TDatedate1,date2,*Pdate,date[31];

第22页/共50页2、对象成员的使用访问对象的成员包括读写对象的数据成员和调用它的成员函数,其访问格式是:

<对象名>.<成员名>

或者

<对象名>.<成员名>(<参数表>)

前者用来表示数据成员的,后者用来表示成员函数的。如:上例中已定义了类Record,则:

Recordbook1,book2;//此处的book1,book2就是Record//类型,也就是类的两个对象可参看教材p125程序5-3-1

第23页/共50页如上例中,对象的主函数如下:voidmain(){Recordbook1,book2;//定义对象book1和book2//调用成员函数regist,给book1的两个数据成员

//bookname和number赋值

book1.regist(“C++编程教程”,1001);//调用成员函数regist,给book2的两个数据成员赋值

book2.regist(“C++语言参考”,1002);//调用成员函数show,显示book1对象的数据成员

//bookname和number的值

book1.show();//调用成员函数show,显示book2对象的数据成员

//bookname和number的值

book2.show();}第24页/共50页如改为下面的代码,则错误:voidmain(){Recordbook1,book2;//由于bookname和number是类Record的私有成员,在类外不能直接使用,即对象不能直接使用。

strcpy(book1.bookname,“C++编程教程”);book1.number=1001;strcpy(book2.bookname,“C++语言参考”);book2.number=1002;book1.show();book2.show();}第25页/共50页访问对象的成员需注意以下几点:对于类的私有成员,只能通过其成员函数来访问,不能在类外对私有成员访问。2.调用成员函数时要在函数名之前加上对象名和"."即可,即先指明对象,再指明成员。也可以采用指向对象的指针来访问,但要在函数名前加上指针变量名和“->”。3.任何对对象私有数据的访问都必须通过向对象发送消息来实现,而且所发送的消息还必须是该对象能够识别和接受的。在C++中,消息发送正是通过公有成员函数的调用来实现的。由于类接口隐藏了对象的内部细节,用户只能通过类接口访问对象,因此,在类设计中必须提供足够的公有接口以捕获对象的全部行为,这正是类设计中的一个最基本的要求。返回第26页/共50页3、对象数组参看教材p305-306第27页/共50页第五节构造函数河析构函数全局变量和静态变量在定义时,将自动赋初值为0;局部变量在定义时,其初始值不固定的。而当对象被定义时,由于对象的意义表达了现实世界的实体,所以一旦定义对象,就必须有一个有意义的初始值,在C++中,在定义对象的同时,给该对象初始化的方法就是利用构造函数。下面分别从三个方面讲述初始化问题:

1、类中数据成员的初始化:构造函数和析构函数

由于在类的定义中不能对数据成员初始化,那么类中数据成员利用构造函数进行初始化。

2、类中常量和引用的初始化:初始化表

3、类中数据成员的初始化:初始化表

4、类的对象初始化:拷贝构造函数第28页/共50页1、构造函数和析构函数

构造函数和析构函数是在类体中说明的两种特殊的成员函数。构造函数的功能是在创建对象时,使用给定的值来将对象初始化。析构函数的功能是用来释放一个对象的,在对象删除前,用它来做一些清理工作,它与构造函数的功能正好相反。下面举一例子来说明构造函数和析构函数的特点:

程序5-1

第29页/共50页classTDate

{

public:

TDate(inty,intm,intd);

~TDate();

intIsLeapYear();

voidPrint();

private:

intyear,month,day;

};

第30页/共50页//类的实现部分

TDate::TDate(inty,intm,intd)

{

year=y;

month=m;

day=d;

cout<<"构造函数已被调用。\n";

}

TDate::~TDate()

{

cout<<"析构函数被调用。\n";

}

intTDate::IsLeapYear()

{

return(year%4==0&&year%100!=0)||(year%400==0);

}

voidTDate::Print()

{

cout<<year<<"."<<month<<"."<<day<<endl;

}

第31页/共50页构造函数的特点如下:

1)构造函数是成员函数,函数体可写在类体内,也可定在类体外。

2)构造函数是一个特殊的函数,

该函数的名字与类名相同;

该函数不指定类型说明,它有隐含的返回值,该值由系统内部使用。

该函数可以一个参数,也可以有多个参数。

3)可以定义多个构造函数。即构造函数可以重载,也就是可以定义多个参数个数不同的函数。.。

4)程序中不能直接调用构造函数,在创建对象时系统自动调用构造函数。

第32页/共50页析构函数的特点如下:1)析构函数是成员函数,函数体可写在类体内,也可定在类体外。2)析构函数也是一个特殊的函数

它的名字同类名,并在前面加“~”字符,用来与构造函数加以区别;

析构函数不指定数据类型,并且也没有参数。3)一个类中只可能定义一个析构函数。4)析构函数可以被调用,也可以系统调用。在下面两种情况下,析构函数会被自动调用。

·如果一个对象被定义在一个函数体内,则当这个函数结束时,该对象的析构函数被自动调用。

·当一个对象是使用new运算符被动态创建的,在使用delete运算符释放它时,delete将会自动调用析构函数。第33页/共50页缺省构造函数和缺省析构函数

在类定义时没有定义任何构造函数时,则编译器自动生成一个不带参数的缺省构造函数,其格式如下:

<类名>::<缺省构造函数名>()

{

}

同理,如果一个类中没有定义析构函数时,则编译系统也生成一个称为缺省析构函数,缺省析构函数是一个空函数,其格式如下:

<类名>::~<缺省析构函数名>

{

}第34页/共50页2、类中常量和引用的初始化上一小节讲述了应用析构函数对数据成员变量的初始化,那么如何初始化常量和引用?(应用初始化表,注意在类定义中不能直接用。)返回#include<iostream.h>classiniti_data{

private:intx;int℞constfloatpi;public:

initi_data(intx1):rx(x),pi(3.14){x=x1;}

voiddisplay(){cout<<"x="<<x<<",rx="<<rx<<",pi="<<pi<<endl;}};

voidmain(){

initi_dataob(100);ob.display();

}

结果:x=100,rx=100,pi=3.14那么,从左边例子中可以看出,初始化表的格式:析构函数:引用名(变量),常量名(常数),…{}

第35页/共50页3、类中对象成员的初始化1.对象成员的概念

C++中允许将一个已定义的类的对象作为另一个类的数据成员,这称为类的组合。当一个类的成员是某一个类的对象时,则称该对象为对象成员(或子对象)。如:

classA

{

};

classB

{

private:

Aa;

public:

};

在类中出现了子对象或称对象成员时,该类的构造函数要包含对子对象的初始化,通常采用成员初始化表的方法来初始化子对象。在成员初始化表中包含对子对象的初始化和对类中其他成员的初始化。下面举一例子说明成员初始化的构造。第36页/共50页#include<iostream.h>

classA

{

private:

intA1,A2;

public:

A(inti,intj){A1=i;A2=j;}

voidprint(){cout<<A1<<“,”<<A2<<endl;}

};

classB

{

private:

Aa;//对象成员

intb;

public:

B(inti,intj,intk):a(i,j),b(k)

{

}

voidprint();

};voidB::print()

{

a.print();

cout<<b<<endl;

}

voidmain()

{

Bb(6,7,8);

b.print();

}该程序的输出结果为:

6,7

8第37页/共50页其中,a(i,j),b(k)是成员初始化表,它有二项,前一项是给子对象a初始化,其格式如下:

<子对象名>(<参数表>)

后一项是给类B的数据成员b初始化。这一项也可以写在构造函数的函数体内,使用赋值表达式语句

b=k;

给类B的数据成员初始化。

第38页/共50页4、类的对象初始化拷贝构造函数是C++中引入的一种新的构造函数。定义一个拷贝构造函数的方式是:类名(const类名&形式参数)

{函数体}

由此可看出:(1)拷贝构造函数的名称与类的名称相同,且它只有一个参数,该参数就是对该类对象的引用。(2)拷贝构造函数的功能是用于实现对象值的拷贝,通过将一个同类对象的值拷贝给一个新对象,来完成对新对象的初始化,即用一个对象去构造另外一个对象。第39页/共50页在下述三种情况下,需要用拷贝初始化构造函数来用一个对象初始化另一个对象。

1)明确表示由一个对象初始化另一个对象时,如:TPointP2(P1);

2)当对象作为函数实参传递给函数形参时,如:上例P=f(N);

3)当对象用为函数返回值时。如果类中没有说明拷贝初始化构造函数,则编译系统自动生成一个具有上术形式的缺省拷贝初始化构造函数。作为该类的公有成员。第40页/共50页实例Example是一个人员信息类。用普通构造函数生成obj1,用拷贝构造函数生成obj2。#include<windows.h>#include<iostream.h>classExample{private:char*name;intnum;public:example(inti,char*str)//构造函数定义

{name=str;num=i;}第41页/共50页example(constExample&x)//拷贝构造函数定义

{num=x.num;}voidlist()//定义显示函数list{cout<<"\数据成员num的值="<<num<<endl<<endl;}};voidmain(){exampleobj1(215,“张立三”);//调用函数Example(inti,char*str)构造obj1exampleobj2(obj1);//使用拷贝构造函数构造obj2obj2.list();//显示obj2的值

……//其它程序部分

}第42页/共50页程序的执行结果是:数据成员num的值=215数据成员num的值=215说明:(1)上例中在main函数中的语句Exampleobj2(obj1);在执行时,系统会自动调用类Example的拷贝构造函数

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论