您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 质量控制/管理 > 程序设计基础第10章
第10章类与对象的实现10.1C++中的类10.2对象及其成员的使用10.3类的特殊成员学习目的:①掌握C++中的类、对象;②掌握构造函数、析构函数、类型转换函数等特殊成员函数;③能够跟踪程序运行中各种成员函数的调用;④了解友元的概念。至第11章10.1C++中的类10.1.1类的说明10.1.2类的定义至第十章面向对象程序设计中的类,最初应该来自分析模型或者设计模型,其中往往对于类所具有的属性和操作都进行了严格定义,几乎可以将这些设计得十分详细的、以图形方式描述的类直接转换成C++的类。10.1.1类的说明C++中类的定义一般分为类的说明部分和类的实现部分。其中类说明的格式如下:classClassName{private:私有数据和函数public:公有数据和函数protected:受保护数据和函数};其中class是关键字。ClassName是用户自定义的C++标识符,VisualC++中类名的风格是所有类的名字都以大写字母C开头,表示这是个类的名字,例如CBook、CStudent等。被花括号围起来的部分称做类体。类成员被分成私有、公有、受保护三类。10.1.1类的说明[例10.1]描述图9.7中所描述的图书类。classCBook{private:char*m_pczName;intm_nPages;intm_nEdition;public:voidGetBookName(char*pName);intGetTotalPages();intGetBookEdition();private:voidSetBookName(char*pName);voidSetTotalPages(intnPages);voidSetBookEdition(intnEdition);public:CBook();};classCPoint{private:intm_x;intm_y;public:voidSetXY(intx,inty);intGetX();intGetY();};[例10.2]定义描述平面上点的类,要求提供成员函数设置点的坐标值、返回点的横纵坐标值等功能。至10.110.1.2类的定义1.成员函数的定义类说明声明了类的内部结构(数据成员),以及类的接口(成员函数的函数原型),类定义给出这些函数功能的具体实现。成员函数的定义格式如下:ReturnTypeClassName::FunctionName(ArgumentList){……}[例10.4]定义CPoint类的成员函数的实现voidCPoint::SetXY(intx,inty){m_x=x;m_y=y;}intCPoint::GetX(){returnm_x;}intCPoint::GetY(){returnm_y;}函数SetXY(intx,inty)是用所提供的函数参数x和y的值去设置CPoint类某个对象的m_x和m_y值。而其他两个函数的实现仅仅是将任何一个CPoint类对象所具有的坐标值返回。10.1.2类的定义2.带缺省参数的成员函数与普通函数一样,成员函数参数可以被指定缺省值,当调用该成员函数时,如果没有显式指明参数,则按照相应的语法规则用参数缺省值作为参数调用该成员函数。classCPoint{……voidSetXY(intx=0,inty=0);……};classCPoint{……voidSetXY(intx,inty);voidSetXY(intx);voidSetXY(inty);……};3重载成员函数voidCPoint::SetXY(intx,inty){m_x=x;m_y=y;}voidCPoint::SetXY(intx){m_x=x;}至10.110.2对象及其成员的使用10.2.1对象实例10.2.2对象成员的引用10.2.3生命周期10.2.4类型转换*10.2.5其它应用至第十章10.2.1对象实例例:CPointpoint1,point2,*pPoint;从类产生解空间对象的过程是一个从一般到特殊的演绎过程,这个过程在C++中有相对应的语法—对象声明。声明对象象声明一个普通变量一样,只不过这里将类看做是类型(抽象类型),具有该类型的变量称为对象。具体格式如下:ClassNameObjectList;程序运行遇到这条语句时,将首先根据point1和point2所属类CPoint计算对象所需存储空间的大小,然后为point1和point2分配存储空间,并将相应的空间以point1和point2作为标识。与利用new运算符创建动态数据对象一样,利用new运算符也可以创建类的动态对象,例如创建CPoint类的动态对象可按如下方式编写程序:CPoint*pPoint=newCPoint;至10.210.2.2对象成员的引用1.通过对象引用对象成员voidmain(){CPointMyPoint1,MyPoint2;//创建两对象,调用缺省构造函数初始化数据成员为0MyPoint1.SetXY(2,3);//设置对象MyPoint1的属性值分别为2和3MyPoint2.SetXY(4,5);//设置对象MyPoint2的属性值分别为2和3intx=MyPoint1.GetX();//调用成员函数得到数据成员m_x的值,并赋值给变量xinty=MyPoint1.GetY();//调用成员函数得到数据成员m_y的值,并赋值给变量ycoutx;yendl;coutMyPoint2.GetX();MyPoint2.GetY()endl;CPoint*pPoint;//定义指向CPoint类对象的指针pPoint=&MyPoint2;//将对象MyPoint2的地址赋值给pPoint,使其指向MyPoint2x=pPoint-GetX();//x的值将等于对象MyPoint2的属性m_x的值CPoint*pPoint1=newCPoint;pPoint1-SetXY(6,7);//设置pPoint1所指对象的属性值CPoint&refPoint=MyPoint1;x=refPoint.GetX();}使用成员选择符.引用对象成员使用成员选择符-用对象成员使用“引用(&)”引用对象成员10.2.2对象成员的引用2.成员函数中引用对象成员隐含成员引用的实现是通过将指向调用函数的对象的指针作为“隐藏”的第一个变元传递给成员函数的,这个指针被命名为this,根据this指针可以知道对象成员的地址。可以使用this指针直接引用对象成员:引用对象成员需使用特定对象,再通过成员选择运算符来进行,但是对类的成员函数而言可以有简单的方式,即直接引用所属类各成员。例如[例10.4]成员函数的定义中对CPoint类数据成员m_x和m_y的引用。对象成员的这种引用方式称为隐含成员引用,或隐式对象的存取。voidCPoint::SetXY(intx,inty){this-m_x=x;this-m_y=y;}CBook*CBook::GetBoolPtr(){……returnthis;}CBook&CBook::GetBoolRef(){……return*this;}至10.210.2.3生命周期1.对象的创建与构造函数程序中的对象也具有生命周期,当问题空间对象出现时,作为解的程序中的对象被创建,然后模拟环境或其它对象对问题空间对象的影响,改变自身状态。问题空间对象消亡时,程序中的对象相应地中止运行,并释放所占据的存储空间,从而被删除。C++的对象将经历从创建、状态演化到删除的整个生命周期,对于对象生命周期的每个阶段,C++都提供相应语法供编程者控制对象行为。构造函数是一种特殊的成员函数,在创建对象时自动调用的,常用于完成对象创建时对数据成员的初始化。形式上,构造函数名字与类名相同,而且没有返回值(类型),即使是void类型也是非法的,只要满足了这两个条件,原则上可以定义任何形式的构造函数,因此构造函数是可以重载的。C++中有两种特殊的构造函数―缺省构造函数和拷贝构造函数,如果类中未定义这两种构造函数,必要时C++编译器自动生成,但自动生成的构造函数有时会引起运行错误。(讲解、调试、运行例10.7,见备注)10.2.3生命周期1.对象的创建与构造函数缺省构造函数的形式为无参数的构造函数,如果编程者未定义这样的构造函数,编译器会自动生成。自动生成的缺省构造函数将调用父类及对象成员的构造函数进行初始化,而对于非类类型的数据成员不做任何操作。注意:如果类中定义有常量,必须由编程者提供与缺省构造函数相应的构造函数。拷贝构造函数用于创建一个与已知对象具有相同属性值的对象。当进行对象赋值、对象作形参的形实结合、函数返回一个对象时都会自动调用相应类的拷贝构造函数。拷贝构造函数的格式是固定的,具体格式如下:ClassName::ClassName(constClassName&obj);注意:如果类中具有指针类型数据成员,通常需要编程者提供自己的拷贝拷贝构造函数10.2.3生命周期2.对象的消亡与析构函数析构函数对象消亡前所调用的最后一个函数。通常用于对象消亡时执行一些清理任务,例如,将对象中保存的一些动态分配的空间释放给操作系统析构函数的定义、使用见下例:[例10.9]构造描述学生自然情况的类,学生的属性有名字、年龄、性别等,该类提供必要的构造函数和析构函数#includestring.h#includeiostream.henumSEX{male,female,unknow};classCStudent{private:char*m_pczName;intm_nAge;SEXm_sSex;public:CStudent(char*pName,intnAge,SEXs);CStudent(char*pName);~CStudent();};CStudent::CStudent(char*pName){coutOBJECTCREATE:pNameendl;m_pczName=newchar[strlen(pName)+1];if(m_pczName!=0)strcpy(m_pczName,pName);m_nAge=-1;//-1表示尚未初始化该属性m_sSex=unknow;}CStudent::CStudent(char*pName,intnAge,SEXs){coutOBJECTCREATE:pNameendl;m_pczName=newchar[strlen(pName)+1];if(m_pczName!=0)strcpy(m_pczName,pName);m_nAge=nAge;m_sSex=s;}CStudent::~CStudent(){coutOBJECTDELETE:m_pczNameendl;delete[]m_pczName;}voidmain(){CStudents1(John,10,male);CStudent*ps=newCStudent(Jane,10,female);deleteps;}至10.2对象初始化时,有时在形式上很象是强制类型转换,但是由于这总是出现在对象说明中,因此C++编译器对此有特殊的解释:CStudentst1=Sophia;CStudentst1(Sophia);CStudentst2=CStudent(Tom);CStudentst2(Tom);CStudentst3=st1;CStudentst3(st1);10.2.4类型转换*1构造函数类型转换构造函数在对象的赋值中有时会充当类型转换的角色,将一个或若干操作数转换成类的对象的形式,这种转换是否合法取决于这些操作数对类的构造函数是否合法。st1=CStudent(Henry);等价于将字符串转换成CStudent类型对象。ClassName::ClassName(Type1,Type2,...,Typen)将类型分别为Ty
本文标题:程序设计基础第10章
链接地址:https://www.777doc.com/doc-3156462 .html