《C语言程序设计VisualC++6.0环境》电子教案-C++面向对象程序设计省公开课金奖全国赛课一_第1页
《C语言程序设计VisualC++6.0环境》电子教案-C++面向对象程序设计省公开课金奖全国赛课一_第2页
《C语言程序设计VisualC++6.0环境》电子教案-C++面向对象程序设计省公开课金奖全国赛课一_第3页
《C语言程序设计VisualC++6.0环境》电子教案-C++面向对象程序设计省公开课金奖全国赛课一_第4页
《C语言程序设计VisualC++6.0环境》电子教案-C++面向对象程序设计省公开课金奖全国赛课一_第5页
已阅读5页,还剩85页未读 继续免费阅读

下载本文档

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

文档简介

本章主要知识点

(1)

C++面向对象程序实例(2)

类与对象(3)

继承与派生(4)

运算符重载本章导读

C语言是一个结构化程序设计语言,它是面向过程,在处理较小规模程序时普通比较轻易实现,而当程序规模较大时,C语言就显示出了它不足。在这种情况下C++应运而生,C++语言是从C语言演变而来,它保留了C语言全部优点,同时也增加了面向对象功效。现在C++已成为程序设计中应用最广泛一个语言。《C语言程序设计》

(VisualC++6.0环境)返回本书目录第10章C++面向对象程序设计1/90第10章C++面向对象程序设计《C语言程序设计》

(VisualC++6.0环境)返回本章导读10.2类与对象10.3继承与派生10.5综合实训10.4运算符重载10.1

C++面向对象程序实例2/90《C语言程序设计》

(VisualC++6.0环境)返回本章目录10.1.2C++语言概述10.1.1C++面向对象程序实例10.1C++面向对象程序实例3/9010.1.1C++面向对象程序实例《C语言程序设计》

(VisualC++6.0环境)返回本节目录2.C++程序实例(2)3.C++程序实例(3)1.C++程序实例(1)4/90【例10.1】定义一个矩形类。(程序名为l10_1.cpp。)#include<iostream.h>classrectangle//定义一个矩形类{public:rectangle(floatlen,floatwid)//结构函数 {length=len; width=wid; } floatGetArea();//申明组员函数,计算矩形面积 floatGetPerimeter();//申明组员函数,计算矩形周长~rectangle(){}//析构函数private:floatlength;//私有数据 floatwidth;

};10.1.1C++面向对象程序实例《C语言程序设计》

(VisualC++6.0环境)返回本节目录1.C++程序实例15/90floatrectangle::GetArea()//组员函数详细实现{ returnlength*width;}floatrectangle::GetPerimeter()//组员函数详细实现{ return2*(length+width);}voidmain(){floatl,w; cout<<"请输入矩形长和宽:"; cin>>l>>w; rectanglex(l,w);//定义一个矩形类对象cout<<x.GetArea()<<endl; cout<<x.GetPerimeter()<<endl;//调用组员函数} 10.1.1C++面向对象程序实例《C语言程序设计》

(VisualC++6.0环境)返回本节目录6/9010.1.1C++面向对象程序实例《C语言程序设计》

(VisualC++6.0环境)返回本节目录实例1功效是定义一个矩形类,该类有长和宽两个数据组员,用来描述矩形静态特征(属性),有结构函数用来用初始化类对象,另外还有计算面积和周长两个组员函数作为该类外部接口,供类外程序访问。当用户输入矩形长和宽之后,将结构一个实例矩形,并输出矩形面积和周长。比如用户输入5,6<CR>,则输出结果为:

30

227/90【例10.2】类派生。(程序名为l10_2.cpp。)#include<iostream.h>classrectangle//定义矩形类{public:voidInitRect(floatlen,floatwid)//定义类组员函数 {length=len; width=wid; } floatGetArea(); floatGetPerimeter();private://定义私有组员变量floatlength; floatwidth;};floatrectangle::GetArea()//组员函数实现{ returnlength*width;}10.1.1C++面向对象程序实例《C语言程序设计》

(VisualC++6.0环境)返回本节目录2.C++程序实例28/90floatrectangle::GetPerimeter()//组员函数实现{ return2*(length+width);}classsquare:publicrectangle//从矩形类中派生新类(正方形类){public: voidInitSquare(floatb){InitRect(b,b);}//新增组员函数(初始化};//正方形)voidmain(){ squarex;//申明正方形类对象 x.InitSquare(8);//调用正方形类新增组员函数cout<<x.GetArea()<<endl;//调用从矩形类中继承下来组员函数cout<<x.GetPerimeter()<<endl;//调用从矩形类中继承下来组员}//函数(GetPerimeter)10.1.1C++面向对象程序实例《C语言程序设计》

(VisualC++6.0环境)返回本节目录9/9010.1.1C++面向对象程序实例《C语言程序设计》

(VisualC++6.0环境)返回本节目录实例2功效是先定义一个矩形类,然后从该矩形类中派生出一个新正方形类(正方形是矩形一个特例)。程序中先申明一个正方形类对象,然后将其初始化为边长为8正方形,再调用从矩形类中继承下来计算面积和周长两个函数,计算出正方形面积和周长。该程序输出结果为:64

3210/90【例10.3】“+”运算符重载。(程序名为l10_3.cpp。)#include<iostream.h>classrectangle//定义一个矩形类{public:rectangle(floatlen=0,floatwid=0)//结构函数 { length=len; width=wid; } floatGetArea(){returnlength*width;}//组员函数(计算面积) rectangleoperator+(rectanglea2)//将"+"运算符重载 {rectanglea;//用于两个矩形对象相加 a.length=length; a.width=width+a2.GetArea()/length;returnrectangle(a.length,a.width); }10.1.1C++面向对象程序实例《C语言程序设计》

(VisualC++6.0环境)返回本节目录3.C++程序实例311/90private://私有组员变量floatlength; floatwidth;};voidmain(){rectanglex(5,9),y(5,6),z;//申明类对象 cout<<"第一个矩形面积为:"<<x.GetArea()<<endl; cout<<"第二个矩形面积为:"<<y.GetArea()<<endl;z=x+y;//对两个矩形相加cout<<"两个矩形面积之和为:"<<z.GetArea()<<endl; }10.1.1C++面向对象程序实例《C语言程序设计》

(VisualC++6.0环境)返回本节目录实例3功效是先定义一个矩形类,然后将“+”运算符重载为能够使两个矩形类对象相加。该程序输出结果为:

第一个矩形面积为:45

第二个矩形面积为:30

两个矩形面积之和为:7512/9010.1.2C++语言概述《C语言程序设计》

(VisualC++6.0环境)返回本节目录因为结构化程序设计本身不足,在20世纪80年代出现了面向对象程序设计方法,C++语言也由此而产生。面向对象程序设计(Object-Orientedprogramming,简称OOP)设计出发点就是为了能更直接描述客观世界中存在事物(即对象)以及它们之间关系。面向对象程序设计是对结构化程序设计继承和发展,它认为现实世界是由一系列彼此相关且能相互通信实体组成,这些实体就是面向对象方法中对象,而对一些对象共性抽象描述,就是面向对象方法中类。类是面向对象程序设计关键。13/9010.1.2C++语言概述《C语言程序设计》

(VisualC++6.0环境)返回本节目录C++是当前最流行面向对象程序设计语言。它在C语言基础上进行了改进和扩充,并增加了面向对象程序设计功效,更适合于开发大型软件。C++是由贝尔试验室在C语言基础开发成功,C++保留了C语言原有全部优点,同时与C语言又完全兼容。它既能够用于结构化程序设计,又可用于面向对象程序设计,所以C++是一个功效强大混合型程序设计语言。C++最有意义方面是支持面向对象程序设计特征。即使与C语言兼容性使得C++含有双重特点,但它在概念上和C语言是完全不一样,学习C++应该按照面向对象程序思维去编写程序。14/90《C语言程序设计》

(VisualC++6.0环境)返回本章目录10.2.2类结构与封装10.2.1面向对象基本概念10.2类与对象10.2.3创建对象10.2.4友元10.2.5模板10.2.6程序实训15/9010.2.1面向对象基本概念《C语言程序设计》

(VisualC++6.0环境)返回本节目录1.对象从普通意义上讲,客观世界中任何一个事物都能够看成是一个对象。比如一本书,一名学生等。对象含有自己静态特征和动态特征。静态特征能够用某种数据来描述,如一名学生身高、年纪、性别等;动态特征是对象所表现行为或含有功效,如学生学习、运动、休息等。面向对象方法中对象是系统中用来描述客观事物一个实体,它是用来组成系统一个基本单位,对象由一组属性和一组行为组成。属性是用来描述对象静态特征数据项,行为是用来描述对象动态特征操作序列。16/90许多对象含有相同结构和特征,比如不论是数学书还是化学书,它们都含有大小、定价、编者等特征。在现实生活中,我们通常将含有相同性质事物归纳、划分成一类,比如数学书和化学书都属于书这一类。一样在面向对象程序设计中也会采取这种方法。面向对象方法中类是含有相同属性和行为一组对象集合。类代表了一组对象共性和特征,类是对象抽象,而对象是类详细实例。比如,家俱设计师按照家俱设计图做成一把椅子,那么设计图就好比是一个类,而做出来椅子则是该类一个对象,一个详细实例。拿【例10.1】中定义矩形类来说,该类只是全部矩形一个蓝本,它只是代表了矩形一些特征,而该类实例则是一个特定矩形。10.2.1面向对象基本概念《C语言程序设计》

(VisualC++6.0环境)返回本节目录2.类17/9010.2.2类结构与封装《C语言程序设计》

(VisualC++6.0环境)返回本节目录1.类封装类封装就是将对象属性和行为结合成一个独立实体,并尽可能隐蔽对象内部细节,对外形成一道屏障,只保留有限对外接口使之和外界发生联络。类组员包含数据组员和组员函数,分别描述类所表示问题属性和行为。对类组员访问加以控制就形成了类封装,这种控制是经过设置组员访问权限来实现。在面向对象程序设计中,经过封装将一部分行为作为外部接口,而将数据和其它行为进行有效隐蔽,就能够到达对数据访问权限合理控制。把整个程序中不一样部分相互影响降低到最低程度。18/9010.2.2类结构与封装《C语言程序设计》

(VisualC++6.0环境)返回本节目录2.类定义类定义普通格式为:class类名称

{

public:

公有数据和组员函数/*外部接口*/protected:

保护数据组员函数private:

私有数据和组员函数

};19/9010.2.2类结构与封装《C语言程序设计》

(VisualC++6.0环境)返回本节目录关键字class说明了类定义开始,类中全部内容用大括号括起来。类组员可分为三种级别访问权限:public(公有):说明该组员是公有,它不但能够被类组员函数访问,而且能够被外界访问,所以说公有类型定义了类外部接口。Protected(保护):说明该组员只能被该类组员函数和该类派生类组员函数访问。Private(私有):说明该组员只能被类组员函数访问,外界不能直接访问它。类数据组员普通都应该申明为私有组员。20/9010.2.2类结构与封装《C语言程序设计》

(VisualC++6.0环境)返回本节目录3.类组员函数类组员函数描述是类行为。定义类时在类定义体中给出函数申明,说明函数参数列表和返回值类型,而函数详细实现普通在类定义体之外给出。下面是类外定义组员函数普通格式:返回值类型类名::类组员函数名(参数列表){

函数体

}

其中::称为作用域分辨符。用它能够限制要访问组员所在类名称。21/90在建立一个对象时,经常需要作一些初始化工作,而当对象使用结束时,又需要作一些清理工作。在C++中提供了两个特殊组员函数来完成这两项工作,那就是结构函数和析构函数。结构函数作用就是在对象在被创建时利用特定值结构对象,将对象初始化。结构函数完成是一个从普通到详细过程。需要注意是结构函数同其它组员函数不一样,它不需要用户触发,而是在创建对象时由系统自动调用,其它任何过程都无法再调用结构函数。结构函数函数名必须与类名相同,而且不能有返回值,也不需加void类型申明。结构函数能够带参数也能够不带参数。结构函数普通定义为公有类型。10.2.2类结构与封装《C语言程序设计》

(VisualC++6.0环境)返回本节目录4.结构函数和析构函数22/9010.2.2类结构与封装《C语言程序设计》

(VisualC++6.0环境)返回本节目录析构函数也是类一个公有组员函数,其作用与结构函数恰好相反,它是用来在对象被删除前进行一些清理工作。析构函数调用之后,对象被撤消了,对应内存空间也将被释放。析构函数名也应与类名相同,只是函数名前加一个波浪符“~”,以区分于结构函数。析构函数不能有任何参数,且不能有返回值。假如不进行显式说明,系统会自动生成缺省析构函数,所以一些简单类定义中没有显式析构函数。5.结构函数与析构函数应用实例23/9010.2.2类结构与封装《C语言程序设计》

(VisualC++6.0环境)返回本节目录【例10.4】程序名为l10_4.cpp。

#include<iostream.h>

classA//定义类A

{public:

A()

{cout<<“结构函数被调用”<<endl;//结构函数

}

voiddisp()//组员函数

{cout<<“结构函数与析构函数应用举例”<<endl;

}

~A()//析构函数

{cout<<"析构函数被调用"<<endl;

}

};24/90程序在申明A类对象时,系统会自动调用结构函数,因而先执行结构函数中输出语句,输出“结构函数被调用”,接下来调用disp组员函数,执行disp组员函数中输出语句,输出“结构函数与析构函数应用举例”,最终程序在退出前由系统自动调用析构函数,执行析构函数中输出语句,输出“析构函数被调用”,所以程序输出结果为:

结构函数被调用结构函数与析构函数应用举例析构函数被调用10.2.2类结构与封装《C语言程序设计》

(VisualC++6.0环境)返回本节目录voidmain()

{Aa;//申明类对象,自动调用结构函数

a.disp();//调用组员函数,对象使用结束时

//自动调用析构函数

}6.实例分析25/9010.2.3创建对象《C语言程序设计》

(VisualC++6.0环境)返回本节目录经过使用数组,我们能够对大量数据和对象进行有效管理,但对于许多程序,在运行之前,我们并不能确切地知道数组中会有多少个元素。比如,一个网络中有多少个可用节点,一个CAD系统中会用到多少个形状等。假如数组开太大会造成很大浪费,假如数组较小则又影响大量数据处理。在C++中,动态内存分配技术能够确保我们在程序运行过程中按实际需要申请适量内存,使用结束后再进行释放。这种在程序运行过程中申请和释放存放单元过程称为创建对象和删除对象。1.new运算符26/90C++用new运算符来创建对象。

运算符new功效是动态创建对象,其语法形式为:

new类型名(初值列表);

该语句功效是在程序运行过程中申请用于存放指定类型内存空间,并用初值列表中给出值进行初始化。

假如创建对象是普通变量,初始化工作就是赋值,假如创建对象是某一个类实例对象,则要依据实际情况调用该类结构函数。

比如:int*p;

p=newint(100);//赋值给指针变量

比如:rectangle*r;

r=newrectangle(5,6);//调用矩形类结构函数

假如创建对象是数组类型,则应按照数组结构来创建,其语法形式为:10.2.3创建对象《C语言程序设计》

(VisualC++6.0环境)返回本节目录27/9010.2.3创建对象《C语言程序设计》

(VisualC++6.0环境)返回本节目录一维数组:new类型名[下标];

当数组为一维数组时,下标为数组为元素个数,动态分配内存时不能指定数组元素初值。假如内存申请成功,返回一个指向新分配内存首地址指定类型指针,假如失败返回0。

比如:int*p;

p=newint[10];

多维数组:new类型名[下标1][下标2]……;

当数组为多维数组时,返回一个指向新分配内存首地址指针,但该指针类型为指定类型数组。数组元素个数为除最左边一维外下标乘积。

比如:int(*p)[5];

p=newint[10][5];28/9010.2.3创建对象《C语言程序设计》

(VisualC++6.0环境)返回本节目录2.delete运算符运算符delete功效是删除由new运算符创建对象,释放指针指向内存空间,其语法形式为:

delete指针名;

比如:int*p;

p=newint(100);

deletep;

假如new运算符创建对象是数组,则删除对象时应使用语法形式为:

delete[]指针名;

比如:int*p;

p=newint[10];

delete[]p;29/9010.2.3创建对象《C语言程序设计》

(VisualC++6.0环境)返回本节目录3.C++程序实例【例10.5】类对象创建与删除。(程序名为l10_5.cpp。)

#include<iostream.h>

classrectangle//定义一个矩形类{public:

rectangle(floatlen,floatwid)//结构函数

{length=len;

width=wid;

}

floatGetArea();//组员函数

private:

floatlength;

floatwidth;

};30/9010.2.3创建对象《C语言程序设计》

(VisualC++6.0环境)返回本节目录floatrectangle::GetArea()//组员函数实现{returnlength*width;

}

voidmain()

{rectangle*r;//定义指向rectangle类指针变量r

r=newrectangle(10,5);//创建rectangle类对象

cout<<r->GetArea()<<endl;

deleter;//删除对象

}4.C++程序实例分析程序中先建立了一个rectangle类,然后在主函数中定义了一个指向rectangle类指针变量r,用new在内存中开辟一段空间以存放rectangle类对象,这时会自动调用结构函数来初始化该对象,接下来使用指向rectangle类指针变量r得到矩形面积,最终用delete删除对象,释放该空间。31/9010.2.4友元《C语言程序设计》

(VisualC++6.0环境)返回本节目录2.友元函数3.友元类1.友元概述32/9010.2.4友元《C语言程序设计》

(VisualC++6.0环境)返回本节目录在程序设计过程中,假如用户建立了一个类,这个类数据组员被定义为私有,这时假如想把该数据存取到某个函数(非该类组员函数)中,那么这么作必定是不被允许。不过有时候一些非组员函数需要亲自访问类中一些私有数据,那么这时候就需要用到友元。友元提供了不一样类或对象组员函数之间、类组员函数与普通函数之间进行数据共享机制。经过友元,一个普通函数或类组员函数能够访问到封装于其它类中数据。友元作用在于提升程序运行效率,但同时它也破坏了类封装性和隐藏性,使得非组员函数能够访问类私有组员。1.友元概述33/9010.2.4友元《C语言程序设计》

(VisualC++6.0环境)返回本节目录友元函数是在类定义中由关键字friend修饰非组员函数。友元函数能够是一个普通函数,也能够其它类中一个组员函数,它不是本类组员函数,但它能够访问本类私有组员和保护组员。友元函数需要在类内部进行申明。其格式以下:

class类名称{类组员申明

friend返回类型友元函数名(参数列表);类组员申明}2.友元函数34/9010.2.4友元《C语言程序设计》

(VisualC++6.0环境)返回本节目录【例10.6】使用友元函数计算两点间距离。程序名为l10_6.cpp。#include<iostream.h>

#include<math.h>

classPoint//定义Point类(点)

{public:

Point(doublexx,doubleyy)//结构函数

{x=xx;

y=yy;}

voidGetxy();//组员函数申明

frienddoubleDistance(Point&a,Point&b);//友元函数申明

private:

doublex,y;//私有组员(点坐标)

};35/90voidPoint::Getxy()//组员函数实现{cout<<“(”<<x<<“,”<<y<<“)”;//输出点坐标

}

doubleDistance(Point&a,Point&b)//友元函数实现

{doubledx=a.x-b.x;//访问私有组员

doubledy=a.y-b.y;

returnsqrt(dx*dx+dy*dy);//两点距离

}

voidmain()

{Pointp1(3.0,4.0),p2(6.0,8.0);//定义Point类对象

p1.Getxy();//调用组员函数

p2.Getxy();

cout<<“\nTheistanceis”<<Distance(p1,p2)<<endl;

//调用友元函数

}

10.2.4友元《C语言程序设计》

(VisualC++6.0环境)返回本节目录36/9010.2.4友元《C语言程序设计》

(VisualC++6.0环境)返回本节目录实例说明:程序在类定义体内申明了友元函数原形,在申明时函数名前加friend关键字进行修饰,友元函数详细实现在类外给出,能够看出友元函数经过对象名可直接访问Point类私有组员,而不需要借用外部接口Getxy。在调用友元函数时同调用普通函数一样,采取直接调用方法,而不需要像调用类组员函数那样必须经过对象。

该程序输出结果为:(3,4)(6,8)Thedistanceis537/9010.2.4友元《C语言程序设计》

(VisualC++6.0环境)返回本节目录3.友元类同函数一样,类也能够申明为另一个类友元,这时称为友元类。当一个类作为另一个类友元时,这个类全部组员函数都将是另一个类友元函数。友元类普通格式为:class类A{类A组员申明friendclass类B;类A组员申明}38/90【例10.7】程序名为l10_7.cpp。#include<iostream.h>classA//定义类A{public: A(intxx,intyy)//类A结构函数 { x=xx; y=yy;

} friendclassB;//申明类B为类A友元类private:

intx,y;};classB//定义类B{public: voiddisp1(As){cout<<"disp1调用了类A私有组员x:"<<s.x<<endl;} //类B组员函数访问类A私有组员

10.2.4友元《C语言程序设计》

(VisualC++6.0环境)返回本节目录39/90程序中定义了A和B两个类,其中类B为类A友元类,定义时在类A内部申明类B,而类B详细实现过程是在类A外部。类B中有两个组员函数disp1和disp2,依据友元类概念,这两个组员函数都成为类A友元函数,所以它们都能够访问类A私有组员x和y。该程序输出结果为:disp1调用了类A私有组员x:5disp2调用了类A私有组员y:910.2.4友元《C语言程序设计》

(VisualC++6.0环境)返回本节目录 voiddisp2(As) {cout<<"disp2调用了类A私有组员y:"<<s.y<<endl;} //类B组员函数访问类A私有组员

};

voidmain(){Aa(5,9);//申明A类对象Bb;//申明B类对象b.disp1(a);//调用B类组员函数b.disp2(a);}40/9010.2.5模板《C语言程序设计》

(VisualC++6.0环境)返回本节目录前面章节中我们学习了重载函数,使用重载函数能够处理各种数据类型,不过即使设计为重载函数也只是使用相同函数名,函数体依然要分别定义。使用函数模板则不一样了,函数模板能够用来创建一个通用功效函数,以支持各种不一样参数,简化重载函数函数体设计。函数模板定义形式为:

template<typename标识符>函数定义1.函数模板41/9010.2.5模板《C语言程序设计》

(VisualC++6.0环境)返回本节目录【例10.8】使用函数模板。(程序名为l10_8.cpp。)#include<iostream.h>template<typenameT>Tmax(Tx,Ty)//定义模板函数{returnx>y?x:y;}voidmain(){inta=6,b=8;cout<<max(a,b)<<endl;doublem=10.5,n=8.5;cout<<max(m,n)<<endl;}程序中首先定义模板函数max用来取得两个数中相对较大一个,然后主函数调用该函数,此时编译器将依据实参类型推导出函数模板类型参数。比如,当调用max(a,b)时,因为a,b为整型变量,所以模板中类型参数T为int,而调用max(m,n)时,因为m,n为double类型,所以模板中类型参数T为double。42/9010.2.5模板《C语言程序设计》

(VisualC++6.0环境)返回本节目录2.类模板使用类模板使用户能够为类定义一个模式,使得类中一些数据组员、一些组员函数参数、一些组员函数返回值能取任意类型,包含用户自定义或系统预定义。

为了定义类模板,应在类申明之前加上一个模板参数表,参数表里形式类型名用来说明组员数据和组员函数类型。类模板定义形式为:

template<class类型说明符>

类定义

类模板本身不产生代码,它指定类一个家族,当被其它代码引用时,类模板才依据引用需要产生代码。43/90【例10.9】使用类模板。(程序名为l10_9.cpp。)

#include<iostream.h>

template<classT>//类模板,实现对任意数据类型存取classrectangle//定义一个矩形类rectangle

{public:

rectangle(Tlen,Twid)//结构函数

{length=len;

width=wid;

}

TGetArea();//申明组员函数,计算矩形面积

TGetPerimeter();//申明组员函数,计算矩形周长private:

Tlength;//私有数据,用于任意类型

Twidth;

};

template<classT>

Trectangle<T>::GetArea()//组员函数详细实现

{returnlength*width;}10.2.5模板《C语言程序设计》

(VisualC++6.0环境)返回本节目录44/90template<classT>

Trectangle<T>::GetPerimeter()//组员函数详细实现

{return2*(length+width);}

voidmain()

{rectangle<int>x(4,6);//定义rectangle对象(组员函数返回值为int型)

rectangle<double>y(5.5,3.8);//定义rectangle对象(组员函数返回值为double型)

cout<<“x面积是:”<<x.GetArea()<<endl;

cout<<“x周长是:”<<x.GetPerimeter()<<endl;

cout<<“y面积是:"<<y.GetArea()<<endl;

cout<<"y周长是:"<<y.GetPerimeter()<<endl;

}程序执行结果为:

x面积是:24

x周长是:20

y面积是:20.9

y周长是:18.610.2.5模板《C语言程序设计》

(VisualC++6.0环境)返回本节目录45/90【例10.10】日期类应用程序举例。(程序名为l10_10.cpp。)

#include<iostream.h>

classTDate//日期类定义

{public:

TDate(inty,intm,intd);//结构函数

intIsLeapYear();//判断闰年

voidshow();//显示日期

friendintGetyear(TDatedate);//友元函数,返回年

private:

intyear,month,day;

};

TDate::TDate(inty,intm,intd)//结构函数实现

{year=y;

month=m;

day=d;

}10.2.6程序实训《C语言程序设计》

(VisualC++6.0环境)返回本节目录1.C++程序实例46/90intTDate::IsLeapYear()

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

voidTDate::show()

{cout<<year<<“年”<<month<<“月”<<day<<“日”<<endl;}

intGetyear(TDatedate)//友元函数实现

{returndate.year;}

voidmain()

{TDate*date;//申明指向TDate类型指针变量

date=newTDate(,10,28);//创建对象

date->show();//调用组员函数

if(date->IsLeapYear())

cout<<Getyear(*date)<<“年是闰年”<<endl;//调用友元函数

else

cout<<Getyear(*date)<<“年不是闰年"<<endl;

deletedate;//删除对象

}10.2.6程序实训《C语言程序设计》

(VisualC++6.0环境)返回本节目录47/9010.2.6程序实训《C语言程序设计》

(VisualC++6.0环境)返回本节目录程序能够分为三个部分,第一部分是CDate类定义,第二部分是组员函数实现,第三部分是主函数。类定义中依然是由组员数据和组员函数组成,其中组员函数作为外部接口。程序中为了说明友元应用,引入了友元函数,这里能够换成类组员函数,读者能够自己试一试。主函数中,在定义了指向TDate类型指针变量之后,使用new运算符创建对象,程序结束时又使用delete运算符删除了对象,释放了内存空间。这种编程方法在以后程序设计中会经常碰到,读者应该习惯于使用new和delete进行动态内存管理。2.C++程序实例分析48/90《C语言程序设计》

(VisualC++6.0环境)返回本章目录10.3.2派生类10.3.1

继承与派生概念10.3继承与派生10.3.4虚函数10.3.3

派生类结构函数与析构函数10.3.5程序实训49/90面向对象程序设计过程中,一个很主要特点就是代码可重用性。C++是经过继承这一机制来实当代码重用。所谓继承指是类继承,就是在原有类基础上建立一个新类,新类将从原有类那里得到已经有特征。比如,现有一个学生类,定义了学号、姓名、性别、年纪四项内容,假如我们除了用到以上四项内容外,还需要用到电话和地址等信息,我们就能够在学生类基础上再增加相关内容,而无须重头再定义一个类。换个角度来说,从已经有类产生新类过程就是类派生。类继承与派生允许在原有类基础上进行更详细、更详细修改和扩充。新类由原有类产生,包含了原有类关键特征,同时也加入了自己所特有性质。新类继承了原有类,原有类派生出新类。原有类我们称为基类或父类,而派生出类我们称为派生类或子类。比如:全部windows应用程序都有一个窗口,能够说它们都是从一个窗口类中派生出来,只不过有应用程序用于文字处理,有则应用于图像显示。10.3.1继承与派生概念《C语言程序设计》

(VisualC++6.0环境)返回本节目录50/9010.3.1继承与派生概念《C语言程序设计》

(VisualC++6.0环境)返回本节目录类继承与派生层次结构是人们对自然界中事物进行分类分析认识过程在程序设计中表达。现实世界中事物都是相互联络、相互作用,人们在认识过程中,依据它们实际特征,抓住其共同特征和细小差异,利用分类方法进行分析和描述。

以下列图是生物类一个继承图,最高层次生物类是抽象程度最高,是最含有普遍意义概念,下层含有上层特征,同时也加入了自己新特征,而最下层是最详细。这个层次结构中,由上到下,是一个详细化、特殊化过程,由下到上,是一个抽象化过程。上下层之间就能够看作是基类与派生类关系。51/9010.3.1继承与派生概念《C语言程序设计》

(VisualC++6.0环境)返回本节目录52/9010.3.2派生类《C语言程序设计》

(VisualC++6.0环境)返回本节目录定义派生类普通形式为:

class派生类名:继承方式基类名

{派生类组员定义};

继承方式指派生类访问控制方式,能够是public(公有继承),protected(保护继承)和private(私有继承)。继承方式能够省略不写,缺省值为private。

派生类在派生过程中,需要经历吸收基类组员、改造基类组员和添加新组员三个步骤。其中,吸收基类组员主要目标是实当代码重用,但应该注意是基类结构函数和析构函数是不能被继承下来;改造基类组员则主要是对基类数据组员或组员函数覆盖,就是在派生时定义一个和基类数据或函数同名组员,这么基类中组员就被替换为派生类中同名组员;添加新组员是对类功效扩展,添加必要数据组员和组员函数来实现新增功效。53/9010.3.2派生类《C语言程序设计》

(VisualC++6.0环境)返回本节目录在继承中,派生类继承了除结构函数和析构函数以外全部组员。对于从基类继承过来组员访问并不是简单把基类私有组员、保护组员和公有组员直接作为私有组员、保护组员和公有组员,而是要依据基类组员访问权限和派生类继承方式共同决定。

1.公有继承

当类继承方式为public时,基类公有(public)组员和保护(protected)组员依然成为派生类公有组员和保护组员,而基类私有组员不能被派生类访问。

2.保护继承

当类继承方式为protected时,基类公有(public)组员和保护(protected)组员将成为派生类保护组员,而基类私有组员不能被派生类访问。54/9010.3.2派生类《C语言程序设计》

(VisualC++6.0环境)3.私有继承

当类继承方式为private时,基类公有(public)组员和保护(protected)组员将成为派生类私有组员,而基类私有组员不能被派生类访问。(看下列图:)返回本节目录55/90如10.1.1中实例2先定义了一个矩形类,然后又从矩形类中派生出正方形类,正方形是矩形一个特例,矩形类实例化一个矩形对象时需要用到长和宽两个参数,而正方形则只需要用到边长一个参数,所以在派生过程中新增了组员函数InitSquare用来完成初始化工作。InitSquare函数实现过程中用到了基类组员函数InitRect,因为InitRect函数为基类公有组员,所以在派生类中能够被访问。假如InitSquare函数实现过程改为以下语句:

voidInitSquare(floatb)

{length=b;

width=b;}

该程序是不能被编译经过,因为派生类是不能访问基类私有组员。另外,该程序使用继承方式为公有继承,所以基类中公有组员都被派生类吸收并成为公有组员。10.3.2派生类《C语言程序设计》

(VisualC++6.0环境)返回本节目录56/9010.3.3派生类结构函数与析构函数《C语言程序设计》

(VisualC++6.0环境)返回本节目录继承目标是为了发展,派生类继承了基类组员,实现了代码重用,这只是一部分,而代码扩充才是最主要,只有添加新组员,加入新功效,类派生才有实际意义。我们知道,基类结构函数和析构函数是不能被继承,所以假如要对新增组员进行初始化,就必须加入新结构函数。一样,对派生类对象扫尾、清理工作也需要引入新析构函数。1.派生类结构函数假如基类对象包含对组员初始化,而在建立派生类对象时,因为基类结构函数不能被继承而无法执行,所以会使基类组员未初始化,所以在设计派生类结构函数57/9010.3.3派生类结构函数与析构函数《C语言程序设计》

(VisualC++6.0环境)返回本节目录时,不但要考虑派生类新增数据组员初始化,还应该考虑基类数据组员初始化。

派生类结构函数普通格式为:

派生类结构函数名(参数列表):基类结构函数名(参数列表)

{

派生类新增组员初始化语句;

}

将【例10.2】改为使用结构函数进行初始化:【例10.11】程序名为l10_11.cpp。

#include<iostream.h>

classrectangle//定义矩形类(基类)

{public:

rectangle(floatlen,floatwid)//基类结构函数 {length=len;

width=wid;

}58/90floatGetArea();

floatGetPerimeter();

private://定义私有组员变量

floatlength;

floatwidth;

};

floatrectangle::GetArea()//基类组员函数实现

{returnlength*width;

}

floatrectangle::GetPerimeter()//基类组员函数实现

{return2*(length+width);

}

classrect:publicrectangle//从矩形类中派生新类(正方形类)

{public:

rect(floatb):rectangle(b,b)//派生类结构函数

{}

};10.3.3派生类结构函数与析构函数《C语言程序设计》

(VisualC++6.0环境)返回本节目录59/9010.3.3派生类结构函数与析构函数《C语言程序设计》

(VisualC++6.0环境)返回本节目录voidmain()

{rectx(8);//申明正方形类对象

cout<<x.GetArea()<<endl;//调用从矩形类中继承

//下来组员函数(GetArea)

cout<<x.GetPerimeter()<<endl;//调用从矩形类中继承下来

//组员函数(GetPerimeter)

}程序输出结果为:64

3260/9010.3.3派生类结构函数与析构函数《C语言程序设计》

(VisualC++6.0环境)返回本节目录2.派生类析构函数在派生过程中,基类析构函数也不能被继承下来,这就需要在派生类中自行定义。派生类析构函数定义与没有继承关系类析构函数完全相同,只要负责把派生类新增组员清理工作做好就够了,系统会自动调用基类析构函数对基类对象组员进行清理。同结构函数相同,析构函数在执行过程中也要对基类进行操作,它首先对派生类新增组员进行清理,然后对基类进行清理。这些清理工作分别是调用派生类析构函数和调用基类析构函数来完成。

61/90【例10.12】程序名为l10_12.cpp。

#include<iostream.h>

classcolor//定义color类

{public:

voidpaint(){cout<<“Nocolor.”<<endl;}

};

classgreen:publiccolor//由color派生出green类

{public:

voidpaint(){cout<<"Thecolorisgreen."<<endl;}

};10.3.4虚函数《C语言程序设计》

(VisualC++6.0环境)返回本节目录虚函数就是在前面使用virtual关键字来限定普通组员函数。虚函数是为实现某种功效而假设函数,它是类一个组员函数。当在派生类中定义了一个同名组员函数时,只要该组员函数参数类型及返回类型与基类中同名虚函数完全一样,那么不论是否用virtual关键字,它都将成为一个虚函数。

我们先看一个例子:62/9010.3.4虚函数《C语言程序设计》

(VisualC++6.0环境)返回本节目录voidmain()

{ colorc,*p;//申明color类变量及指针变量

greeng;//申明green类变量

p=&g;//将指向color类指针p指向green类

c.paint();

g.paint();

p->paint();

}程序执行结果如右图:63/9010.3.4虚函数《C语言程序设计》

(VisualC++6.0环境)程序中对象c和对象g输出结果都不难了解,但指针p已经指向了green类对象,然而从输出结果看调用却是color类paint()函数。处理这个问题方法就是使用虚函数。

将上例color类改为以下使用虚函数方法:classcolor//定义color类

{public:

virtualvoidpaint(){cout<<"Nocolor."<<endl;}//定义虚函数

};输出结果如右图:返回本节目录64/9010.3.4虚函数《C语言程序设计》

(VisualC++6.0环境)返回本节目录以上实例说明在C++中,假如一个函数被定义成虚函数,那么,即使是使用指向基类对象指针来调用该组员函数,C++也能确保所调用是正确特定于实际对象组员函数。65/9010.3.5程序实训《C语言程序设计》

(VisualC++6.0环境)返回本节目录使用类派生编程实现在屏幕上显示某学生选课信息。学生包含姓名和学号两个属性,选课信息包含课程名称、任课教师和上课时间三个属性,每名学生最多可选三门课。因为学生包含两个属性,选课信息包含三个属性,而这些属性都能够用字符数组表示,那么抓住这个共性我们就能够考虑建立一个基类(base),使其含有两个字符数组类型组员变量,接下来我们就能够由该基类派生出学生类(student)和选课信息类(classes)。为了显示相关信息,在派生过程中,需要增加对应外部接口。程序详细实当代码以下:66/9010.3.5程序实训《C语言程序设计》

(VisualC++6.0环境)【例10.14】程序名为l10_14.cpp。#include<iostream.h>

#include<string.h>

classbase//定义基类base

{private:

charstr1[20];

charstr2[10];

public:

base(){}

base(chars1[],chars2[])

{strcpy(str1,s1);

strcpy(str2,s2);

}

voidshow1()

{cout<<str1;

}返回本节目录67/9010.3.5程序实训《C语言程序设计》

(VisualC++6.0环境)返回本节目录voidshow2()

{cout<<str2;

}

};

classclasses:publicbase//从基类派生课程类

{private:

charcname[20];//课程名称

public:

classes(){}

classes(charcna[],charcweek[],charctea[]):base(cweek,ctea)

//课程名称、上课时间、任课教师

{strcpy(cname,cna);}68/90voidshow()

{cout<<cname<<“(”;

show1();//课程名称(任课教师,上课时间)

cout<<“,”;

show2();

cout<<“)”;

}

};

classstudent:publicbase//从基类派生学生类

{private:

classescls[3];//每名学生最多项选择修3门课

intmax;

public:

student(){}

student(charsname[],charsno[]):base(sname,sno){max=0;}10.3.5程序实训《C语言程序设计》

(VisualC++6.0环境)返回本节目录69/9010.3.5程序实训《C语言程序设计》

(VisualC++6.0环境)返回本节目录voidselectcls(classesc)//选课 { cls[max]=c;

max++;

}

voidshowcls()//显示选课信息

{cout<<“学生:”;

show1();

cout<<"(";

show2();

cout<<")"<<endl<<"选修课程:"<<endl;

for(inti=0;i<max;i++)

{cout<<i+1<<":";

cls[i].show();

cout<<endl;

}

}

};70/9010.3.5程序实训《C语言程序设计》

(VisualC++6.0环境)返回本节目录voidmain(){studentstu("黄雪菲","12345678");classescls1("数据库应用","曲子研","星期三");classescls2("C++程序设计","胡小燕","星期二");classescls3("数据结构","江山","星期五");stu.selectcls(cls1);stu.selectcls(cls2);stu.selectcls(cls3);stu.showcls(); }程序执行结果如右图:71/90《C语言程序设计》

(VisualC++6.0环境)返回本章目录10.4.2运算符重载规则10.4.1重载运算符10.4运算符重载10.4.3类型转换与转换函数72/9010.4.1重载运算符《C语言程序设计》

(VisualC++6.0环境)返回本节目录运算符重载增强了C++语言可扩充性。在C++中,定义一个类就是定义了一个新类型。所以,类对象和变量一样,能够作为参数传递,也能够作为返回类型。在基本数据类型中,系统提供了许多预定义运算符,而实际上,对于用户自定义类型(比如类),也需要有类似运算操作,这就提出了对运算符进行重新定义,赋于已经有符号以新功效要求。运算符重载实质是函数重载。所谓函数重载简单地说就是赋给同一个函数名多个含义,C++中允许在相同作用域内以相同名字定义几个不一样函数,能够是组员函数,也能够是非组员函数,定义重载函数时要求函数参数或者最少有一个类型不一样,或者个数不一样,而对于返回值类型能够相同,也能够不一样。对于每一个运算符@,都对应于一个73/9010.4.1重载运算符《C语言程序设计》

(VisualC++6.0环境)返回本节目录运算符函数operator@,比如“+”对应运算符函数是operator+。运算符重载在实现过程中首先把指定运算符转化为对运算符函数调用,再把运算对象转化为运算符函数实参,然后依据实参类型来确定需要调用运算符函数。

比如在10.1.1实例3中,我们把“+”重载为矩形类组员函数,那么就可直接进行两个矩形类对象相加了。能够看出,运算符重载除了在函数申明时使用了关键字operatore之外,其它地方与类普通组员函数没什么区分,只不过它能够直接经过运算符和操作数方式来完成函数调用。运算符重载扩充了运算符原有功效,如10.1.1实例3中对“+”进行了运算符重载之后,“+”原有功效不变,对整型、浮点型数据运算依然遵照C++预定义规则,同时又增加了针对矩形类运算功效。“+”作用于不一样对象上,就会造成不一样操作行为,含有了更广泛功效。74/9010.4.2运算符重载规则《C语言程序设计》

(VisualC++6.0环境)返回本节目录运算符重载规则以下:1)C++中运算符除了少数几个外,全部能够重载,而且只能重载已经有这些运算符。

2)重载之后运算符优先级和结合性保持不变。

3)运算符重载是针对新类型数据实际需要,对原有运算符进行适当改造。普通来讲,重载功效应与原有功效相类似,不能改变原有运算符操作对象个数,同时最少有一个操作对象是自定义类型。

不能重载运算符有五个,它们是是类属关系运算符“.”、指针运算符“*”、作用域运算符“::”、三目运算符“?:”和sizeof运算符。

运算符重载形式有两种,重载为类组员函数和重载为友元函数。重载为类组员函数普通形式为:75/90《C语言程序设计》

(VisualC++6.0环境)返回本节目录类名称operator运算符(参数表)

{

函数体

}重载为友元函数普通形式为:

friend函数类型operator运算符(参数表)

{

函数体

}10.4.2运算符重载规则76/9010.4.2运算符重载规则《C语言程序设计》

(VisualC++6.0环境)返回本节目录函数类型指定了重载运算符返回值类型,operator是定义运算符重载函数关键字,运算符是C++中可重载运算符。当运算符重载为类组员函数时,双目运算符仅有一个参数,而单目运算符则不能显式说明参数。普通情况下,单目运算符最好重载为组员函数,双目运算符最好重载为友元函数,双目运算符重载为友元函数比重载为组员函数更方便操作,不过,有双目运算符重载为组员

温馨提示

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

评论

0/150

提交评论