您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 质量控制/管理 > 3C++面向对象程序设计
VisualC++面向对象编程语言第三章C++面向对象程序设计第三章C++面向对象程序设计•3.1面向对象程序设计概述•3.1.1传统的结构化程序设计•3.1.2面向对象程序设计方法及特征•3.2C++类•3.2.1类的定义与实现•3.2.2构造函数和析构函数•3.2.3this指针•3.2.4静态成员•3.2.5友元•3.3类的继承•3.3.1基类和派生类•3.3.2基类和派生类的构造函数•3.3.3多重继承•3.3.4虚基类•3.4多态性和虚函数•3.4.1用基类指针指向派生类对象•3.4.2虚函数•3.4.3抽象类和纯虚函数•3.5重载•3.5.1函数重载•3.5.2运算符重载•3.6C++模板•3.6.1函数模板•3.6.2类模板•3.7MicrosoftVisualC++的语法扩充•3.7.1VisualC++自定义数据类型•3.7.2VisualC++运行库•3.7.3运行时类型识别•3.7.4编程规范•结构化程序设计:将系统分解为若干模块(即函数);•缺点:维护困难,特别是数据结构的修改;•3.1.1传统的结构化程序设计•3.1.2面向对象程序设计方法及特征•对象=数据+作用于这些数据上的操作;•类是具有相同数据结构和相同操作功能的对象的集合,对象是类的实例;•对象与类的关系类似于鞋和生产鞋的模具;•面向对象程序设计把一个复杂的问题分解为多个能完成独立功能的对象,分开独立设计,再将其整合完成复杂问题;•其理想目标是希望编写程序就像搭积木;面向过程和面向对象的区别面向过程就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候一个一个依次调用就可以了。面向对象是把构成问题事务分解成各个对象,建立对象的目的不是为了完成一个步骤,而是为了描叙某个事物在整个解决问题的步骤中的行为。例如五子棋,面向过程的设计思路就是首先分析问题的步骤:1、开始游戏,2、黑子先走,3、绘制画面,4、判断输赢,5、轮到白子,6、绘制画面,7、判断输赢,8、返回步骤2,9、输出最后结果。把上面每个步骤用分别的函数来实现,问题就解决了。而面向对象的设计则是从另外的思路来解决问题。整个五子棋可以分为:1、黑白双方,这两方的行为是一模一样的,2、棋盘系统,负责绘制画面,3、规则系统,负责判定诸如犯规、输赢等。第一类对象(玩家对象)负责接受用户输入,并告知第二类对象(棋盘对象)棋子布局的变化,棋盘对象接收到了棋子的变化就要负责在屏幕上面显示出这种变化,同时利用第三类对象(规则系统)来对棋局进行判定。可以明显地看出,面向对象是以功能来划分问题,而不是步骤。同样是绘制棋局,这样的行为在面向过程的设计中分散在了总多步骤中,很可能出现不同的绘制版本,因为通常设计人员会考虑到实际情况进行各种各样的简化。而面向对象的设计中,绘图只可能在棋盘对象中出现,从而保证了绘图的统一。功能上的统一保证了面向对象设计的可扩展性。比如我要加入悔棋的功能,如果要改动面向过程的设计,那么从输入到判断到显示这一连串的步骤都要改动,甚至步骤之间的循序都要进行大规模调整。如果是面向对象的话,只用改动棋盘对象就行了,棋盘系统保存了黑白双方的棋谱,简单回溯就可以了,而显示和规则判断则不用顾及,同时整个对对象功能的调用顺序都没有变化,改动只是局部的。•在类的定义中,数据称为成员变量,函数称为方法;•成员变量按访问控制权限分为公有和私有;•定义的格式:class类名{private:私有数据成员和成员函数的声明public:私有数据成员和成员函数的声明protected:保护数据成员和成员函数的声明}3.2.1类的定义与实现•private属性的成员只允许被本类的成员函数访问和调用;•protected属性的成员允许被本类的成员函数和派生类的成员函数访问和调用;•例:Time类的定义classTime{private:inthour;intminute;intsecond;public:voidsetTime(int,int,int);voidshowTime();}为什么需要这两个函数???对于成员函数来讲,成员变量就像全局变量;•类的定义和一般函数定义类似,但必须在成员函数名前加类名和作用域限定符(::)•Time类的实现(定义)voidTime::setTime(inth,intm,ints){hour=(h=0&&h24)?h:0;minute=(m=0&&m60)?m:0;second=(s=0&&s60)?s:0;}voidTime::showTime(){couthour‘:’minute‘:’secondendl;}•对象的声明:就像变量的声明(用模具生产一个产品);•格式:类名对象名;•例:Timet1,today;Time*pt1=&t1;•比较inti;•成员函数的调用:t1.setTime(1,2,3);today.showTime();pt1-setTime(1,2,3);•思考:t1.hour=10;在面向对象程序设计中,程序设计范型变成了:确定你需要哪些类型,为每个类型提供完整的一组操作。•思考:如果对于Time类,在未调用setTime前调用showTime会怎样?•我们需要对成员变量初始化;•构造函数是一种特殊的成员函数,函数名和类名相同,提供了对成员变量初始化的方法,使得声明对象时自动初始化对象,当声明对象时,自动调用构造函数;•析构函数也是成员函数,用来在系统释放对象前做一些清理工作,当对象注销时,自动调用析构函数;3.2.2构造函数和析构函数•构造函数的名称与类名相同,而析构函数必须在类名前加“~”,都没有返回值;•构造函数可以有参数,析构函数没有参数;•系统有默认的构造函数和析构函数;•可以有多个构造函数(参数类型不同),使得创建的对象根据数据类型的不同(整型和实型)进行不同的处理,这就是函数重载;•public:Time(int,int,int);~Time()……};Time::Time(inth,intm,ints){hour=h;minute=m;second=s;}Time::~Time(){……•例Voidmain(void){Timet1(10,20,30);//调用构造函数…………}//调用析构函数理解面向对象设计的思想例:计算一个矩形的面积和周长计算一个矩形的面积和周长从面向过程的角度出发思考这个问题;先确定面积和周长的算法(这个很简单,小学知识)编写2个方法分别计算面积和周长,在一个类里面考虑到计算周长和面积需要至少2个参数,长和宽;程序如下:intperimeter(intlength,intwidth){return2*(length+width);}intarea(intlength,intwidth){returnlength*width;}voidmain(){coutperimeter(4,5);cout“\n”coutarea(4,5);}下面再从面向对象的角度出发,重新考虑这个问题:一个长方形可以看成一个长方形对象。既然是对象,那么它就有属性(长和宽)和行为(周长和面积)抽取长方形的共性,设计一个类通过对象的行为,就可以求出某个具体的长方形对象的周长和面积classRectangle(){public:intlength,width;intperimeter(){return2*(length+width);}intarea(){returnlength*width;}}voidmain(){Rectanglerect1=newRectangle();rect1.length=10;rect1.width=5;coutrect1.perimeter();coutrect1.area();}•在C方案中扩展困难,原因就在于没有一个合适的位置来存储辅助的状态信息,因为在原来的情况下根本不需要状态信息;•对象提供了一个理想的位置来放置状态信息,并且作为对象的一部分是显示可用的,而不是隐藏在幕后的东西;继续思考面向对象的特点在面向过程的思想里,一个程序一般都是由一个个函数组成的,这些函数之间相互调用,就形成了一个完整的程序,解决了一个问题。它的基本结构是:函数一(){……;}函数二(){……;}……主函数(){……;}在面向对象的思想中,是把这些都封装起来,形成一个类。class类名{函数一(){……;}函数二(){……;}……}然后由这个类产生一个对象,比如:我们把一个类的类名起为student那么产生对象的方法就是:students1;这里s1是一个对象,产生了这个对象以后,才可以进行相关操作。操作方法如:s1.函数一();假设我们要做一个小游戏,类似于网游里面的打怪,为简单起见,认为怪不打人,只让人打,他的血不断减少,直到死亡。把所有怪物的共同特征抽象出来,于是我们得到一个类:怪物class怪物{char怪物名;int血;}怪物::怪物(怪物名n,血n)/*构造函数*/{怪物名=怪物名n;血=血n;}怪物::被打函数(){血减少;}怪物::判断函数(){if(血==0)cout“你胜利了!”;}怪物::玩游戏(){while(血0){被打函数();判断函数();}main主函数voidmain(){/******产生对象******/怪物怪物1(狼,5000);怪物怪物2(虎,8000);怪物怪物3(蛇,3000);怪物1.玩游戏();怪物2.玩游戏();怪物3.玩游戏();}•指向对象本身的指针,作为隐含参数传给每个成员函数;•例:voidTime::showTime(){couthour’:’minute‘:’secondendl;}等同于voidTime::showTime(Time*this);{coutthis-hour‘:”this-minute……}3.2.3this指针Time::showTime{Display(this);}Display(Time*pObj)•This指针对于在非本类成员函数中使用对象成员变量•需要让多个对象共享相同值的成员时使用;•成员变量定义:staticintm_ncount;•使用和一般成员变量一样,也有公有、私有之分;•初始化必须在类定义的外部:intPerson::m_nCount=0;3.2.4静态成员•成员函数也可以是静态的;•定义staticintGetCount();•没有this指针;•可以通过类调用:Person::GetCount();也可以通过对象调用:e1.GetCount();•静态成员函数只能访问类的静态成员;•如需访问非静态成员,需将对象作为参数传入;longPerson::GetID(Personx);3.2.5友元•友元函数:访问其他类的私有成员变量的函数;•一个类可以声明一个函数为其友元函数;•作用:编程方便;•定义:classA{friendvoiddisplay(A);private:inta;}•voiddisplay(Ae){coute.a}voidmain(){……display(a1);}•classB{public:voidfun1(A&)}classA{friendvoidB::fun1(A&);private:inta;}voidB::fun1(A&e){e.a=10;……}一个类的成员函数作为另一个类的友元函数•voidmain(){Aa1;Bb1;b1.fun1(a1);}•友元类:类A可以声明类B为其友元类,类B的所有成员函数都可以访问A的所有成员;•定义classC{public:voidfun2(A&);}classA{friendC;private:inta;}
本文标题:3C++面向对象程序设计
链接地址:https://www.777doc.com/doc-428125 .html