面向对象第四章类与对象软件设计思想发展史为何需要面向对象设计面向对象设计相对应的是两种设计思想各自的显著特征两种设计思想的主要内容——算法+数据对象+对象+…两种设计思想是矛盾对立的吗?作坊式——结构化面向过程——否设计数据结构、设计算法封装对象属性特征(数据)功能(算法)——程序规模用面向对象的眼光考察整数对象:如何描述——数据有哪些功能——运算封装(Encapsulation)——面向对象程序设计的最基本技术(特征),把数据(属性)和函数(操作)合成一个整体,称为“类”(对象)。“整型”:描述了数据特性和运算特性的封装体——取描述一类对象特征之义本章内容4.1类与对象4.5运算符的重载4.4引用与复制构造函数*4.2从面向过程到面向对象4.9名字空间域和类域(选读)4.10面向对象的程序设计和Windows编程4.8结构4.7静态成员4.6友元4.3构造函数和析构函数4.1类与对象何为对象——目光所及、心中所想,一切个体某个数据:某个整数、某个复数、某个分数、某个图形、某本图书…某个问题:一个程序某个对象:鼠标、菜单、对话框…何为类——同类对象特征的总体描述某种数据:整型、复数型、分数型…某类问题:数据的输入输出某类对象:鼠标类、菜单类、对话框类…马白马2个整数加运算画个闹钟2个复数加运算画个幽灵认识和使用对象先要明确对象的特征面向对象设计的关键性工作——类的描述(定义)Complexc1,c2;c1+c2进一步认识对象和面向对象设计inti,j;i+j——类C++类的定义表——表针样式、表盘样式、颜色等;调节旋钮、mp3功能等。整型——存储方式;四则运算、输入输出等。矩形——矩形参数;创建矩形、修改参数、计算参数、输出参数等。商品——名称、数量、单价、总价等;输入商品数据、计算总价、修改商品数据等。类——描述某类数据(对象)的特征和功能。以商品为例,描述一个商品类——描述特征和功能:classCGoods{//attributes,datamemberscharName[21];//商品名intAmount;//商品数量floatPrice;//单价floatTotal_value;//总价public://functions,functionmembersvoidRegisterGoods(char[],int,float);//输入数据voidCountTotal();//计算总价voidGetName(char[]);//读取商品名intGetAmount();//读取商品数量floatGetPrice();//读取商品单价floatGetTotal_value();//读取商品总价};功能描述只有函数声明,未定义以CGoods为例看类的完整定义方法(2种)成员函数先声明后定义成员函数在类中直接定义classCGoods{charName[21];intAmount;floatPrice;floatTotal_value;public:voidCountTotal();//声明…};voidCGoods::CountTotal(){Total_value=Price*Amount;}classCGoods{charName[21];intAmount;floatPrice;floatTotal_value;public:voidCountTotal(){Total_value=Price*Amount;}…};注意::运算符的使用accessspecifier:public:类以外可访问。private:类以外不能访问。protected:介于前两者之间,派生类可访问。封装(Encapsulation)接口(interface)——数据成员私有化,函数成员公有化。则公有函数成为访问对象数据的接口。类起始点无访问说明符时默认为私有类名{数据+对数据的操作}对数据私有化的限制成员函数可以直接使用类定义中的任一成员,可以处理数据成员,也可调用函数成员。注意:类是一种数据类型,定义时系统不为类分配存储空间,所以不能对类的数据成员初始化。创建对象(定义对象)——像定义变量一样CGoodsCar,Watch;对象的使用——创建并使用对象类和对象的关系普遍性(共性)和特殊性(个性)的关系数据类型和变量的关系对象的应用——对象.成员对象是类的实例(instance)。类只是一个样板,以此样板可以在内存中开辟出同样结构的实例——对象。【例4.1】商品类对象应用实例【例4.1】商品类对象应用实例:#includeiostream#includeiomanip#includestringusingnamespacestd;//省略了类定义intmain(){CGoodscar;charstring[21];intnumber;floatpr;成员名Name[21];Amount;Price;Total_value;10minicar5210minicar52string[21]numberPrminicar52minicarcout“请输入汽车型号:”;cin.getline(string,20);//输入串长必须小于20cout“请依次输入汽车数量与单价:”;cinnumberpr;car.RegisterGoods(string,number,pr);car.CountTotal();string[0]=’\0’;//字符串string清零car.GetName(string);//把car.Name赋值给stringcoutsetw(20)stringsetw(5)car.GetAmount();//Acoutsetw(10)car.GetPrice()setw(20)car.GetTotal_value()endl;//Breturn0;}CGoodscar,watch;car.RegisterGoods(“santana”,10,300000);car.CountTotal();coutcar.GetTotal_Value();watch.RegisterGoods(“omigar”,50,15000);watch.CountTotal();coutwatch.GetName()watch.GetAmount()watch.GetPrice()watch.GetTotal_Value();【例】商品类应用程序。Cgoods.cpp【例】复数Complex1.cpp如何封装对象通用对象——属性与操作尽量完备以满足通用性。非通用对象——从关注的属性和操作出发,能够满足特定使用要求即可。对象存储:图4.1各对象完全独立地安排内存的方案图4.1是系统为每一个对象分配了全套的内存。数据区安放成员数据,代码区安放成员函数。注意:不同对象的数据成员的内容是不一样的;而行为(操作)是用函数来描述的,这些操作的代码对所有对象都是一样的。数据区代码区对象1对象2数据区代码区对象n......数据区代码区图4.2各对象的代码区共用的方案数据区对象1数据区对象2数据区对象n......公共代码区图4.2仅为每个对象分配一个数据区,代码区(放成员函数的区域)为各对象类共用。图4.1对应的是在类说明中定义函数,而图4.2对应的是在类说明外部定义函数。*4.2从面向过程到面向对象(阅读)结构化程序设计特点:“自顶向下,逐步细化(divideandconquer,stepwiserefinement)”的思想;模块化操作方法是。函数为一个功能模块模块化思想中的封装:把数据封装为局部变量。问题:模块是功能的抽象,而数据则具有个性,一但发生变化,抽象的功能模块就不再适用了,故可维护性差。对象概念:“对象”是面向对象技术的核心。它就是现实世界中某个具体的物理实体在计算机逻辑中的映射和体现。结构化程序设计弱点:当软件规模过大,数据与数据处理方法分离使得结构化设计的思想很难贯彻到底。对象类计算机世界抽象实例化映射实体抽象类别现实世界客观世界抽象主观世界图4.3对象、实体与类面向对象是计算机世界对现实世界的真实模拟4.2结束4.3、4.4构造函数和析构函数初始化对象——构造函数(constructor)在撤销对象时做点其他事情——析构函数(destructor)4.3.1构造函数的定义与使用4.3.2析构函数的定义4.3.1构造函数的定义与使用构造函数的意义构造函数——通过参数初始化数据成员inti;CGoodscar;inti=10;创建对象时如何初始化?构造函数特征:1.函数名与类名相同。2.构造函数无函数返回类型说明。注意是什么也不写,也不可写void!3.在程序运行时,当新的对象被建立,该对象所属的类的构造函数自动被调用,在该对象生存期中也只调用这一次。(一个对象仅初始化一次)4.构造函数可以重载。严格地讲,说明中可以有多个构造函数,它们由不同的参数表区分,系统在自动调用时按一般函数重载的规则选一个执行。4.3.1构造函数的定义与使用4.3.1构造函数的定义与使用5.构造函数可以在类中定义,也可以在类外定义。6.如果类说明中没有给出构造函数,则C++编译器自动给出一个默认的构造函数:类名(void){}但只要我们定义了一个构造函数,系统就不会自动生成默认的构造函数。只要构造函数是无参的或各参数均有默认值的,C++编译器都认为是默认的构造函数,并且默认的构造函数只能有一个。4.3.1构造函数的定义与使用CGoods的构造函数:三参数:Cgoods(char*name,intamount,floatprice){strcpy(Name,name);Amount=amount;Price=price;Total_value=price*amount;}两参数:货名和单价,Cgoods(char*name,floatprice){strcpy(Name,name);Price=price;Amount=0;Total_value=0.0;}默认的构造函数:CGoods(){Name[0]=‘\0’;Price=0.0;Amount=0;Total_value=0.0;}这三个构造函数同时被说明(重载)。4.3.1构造函数的定义与使用构造函数应用:CGoodsCar1(“夏利2000”,30,98000.0);调用了CGoods中的第一个构造函数,等效于:CGoodsCar1=CGoods(“夏利2000”,30,98000.0);CGoodsCar2(“桑塔那2000”,164000.0);调用的是第二个构造函数,参数为两个。CGoodsCar3;定义时调用不带参数的构造函数但是定义对象时不能加括号。例如:CGoodsCar4();Car4()是不带参数的函数,它的返回值是类CGoods的对象。【例4.1_1】完整商品类对象应用实例【例】复数Complex2.cpp4.3.2析构函数的定义析构函数(destructor)特征:当一个对象的生命周期结束时,C++会自动调用析构函数(destructor)对该对象并进行善后工作,1.构函数名与类名相同,但在前面加上字符‘~’,如~CGoods()。2.析构函数无函数返回类型,与构造函数在这方面是一样的。但析构函数不带任何参数。3.一个类有一个也只有一个析构函数,这与构造函数不同。析构函数可以默认。4.对象注销时,系统自动调用析构函数。【例4.2】定义一个矩形类4.4引用与复制构造函数4.4.1引用4.4.2复制构造函数4.4.3成员对象与构造函数4.4.1引用引用的定义:引用是给一个已经定义的变量重新起一个别名,而不是定义一个新的变量,定义的格式为:类型&引用变量名=已定义过的变量名;例如:doublenumber;double&newnum=number;newnum是新定义的引用类型变量,它是变量number的别名。引用主要用于函数之间的数据传递。4.4.1引用newnum是