深入类和对象_第1页
深入类和对象_第2页
深入类和对象_第3页
深入类和对象_第4页
深入类和对象_第5页
已阅读5页,还剩21页未读 继续免费阅读

下载本文档

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

文档简介

C++程序设计与实践第六章深入类和对象电子科技大学信息与软件工程学院刘梦娟上次课的内容回顾1、深复制和浅复制2、禁止复制3、对象的三种创建方法4、对象的初始化方法5、this指针6、指向类对象的指针7、指向类成员的指针8、友元关系例子7_1.cpp浅复制headList1tailNULLheadList2tail??????深复制List1headtailNULLList2headtailNULL禁止复制就是在private段中声明一个复制构造函数,但不给出定义。例如:classList{private: List(constList&);//declaretiononly //othermembers};对象的创建(1)命名的自动对象类名对象名注意对象的生命周期(2)匿名的自动对象临时对象,只在函数调用返回时产生(3)动态对象利用new运算符创建,对象在程序运行期一直存在;例子7_2.cpp,为什么调用了两次复制构造函数例子7_3.cpp,new/delete创建和销毁对象对象的初始化对象的复制复制初始化主要施加在类对象上。实际上,复制的过程是引起类对象某个版本的构造函数调用。有三种方式可以引起类对象构造函数的调用:构造函数没有参数,或全部参数都可缺省,采用如下语法类名对象;构造函数只有一个参数,可以采用直接初始化方式:类名对象(参数)也可以采用复制初始化方式:类名对象=参数;构造函数有多于一个参数,采用直接初始化方式:类名对象(参数列表);例子7_4.cpp对象和指针this指针:指向对象本身的指针指向类对象的指针语法:类类型*指针名;定以后,通过使用&和->运算符访问对象成员指向类成员的指针指向类成员的指针不属于类,它们定义在类的外部,其语法为:类型名类名::*指针;

类型名(类名::*指针)(参数表);例子7_5.cpp友元关系友元函数友元类友元函数的例子:计算两个点之间的距离参见例子7_6.cpp6.5.2友元类如果将一个类A声明为类B的友元类,那么,类A的所有成员函数都成为类B的友元函数。classPainter;

classRectangle//简化版{private: int width,height; //othermemberspublic:

friendclassPainter;};

classPainter{public:voiddraw(constRectangle&r){cout<<r.width<<','<<r.height<<endl;}};6.6与类和对象相关的问题6.6.1对象数组对象数组的每个数组元素都是一个对象需要多次调用构造函数释放对象数组时,也需要多次调用析构函数例如:RectanglerectArr[10];参见例子7_7.cpp6.6与类和对象相关的问题要创建一个类的对象数组,该类的构造函数必须满足下列几个条件之一:没有显式定义的构造函数;有显式定义的构造函数,但其中有一个构造函数没有参数;有显式定义的构造函数,但其中有一个构造函数的所有参数都可以默认;除了直接定义对象数组外,还可以使用new运算符来动态创建对象数组。例如:Rectangle*p=newRectangle[3];而在使用完毕后,可以使用delete运算符来释放整个数组。例如:delete[]p;6.6.2类对象做为函数参数和返回值对象作为函数参数voidf(Rectangler);//值参数【复制构造函数】voidg(Recangle*r);//指针参数voidh(Rectangle&r);//引用参数对象的值做参数,对形参对象的任何修改都不影响用作实参对象。对象引用做参数,对形参对象的任何修改就是直接对实参对象的修改。一般情况下,选择常量引用作为参数是一种非常好的选择。对象指针做参数,对它指向的对象作任何修改就是间接对实参对象的修改;而修改参数本身将会导致参数指针指向别的对象,对实参对象没有任何影响。参见例子7_8.cpp6.6.2类对象做为函数参数和返回值2.函数返回对象Rectanglef(Rectangler){returnr;}//返回值Rectangle*g(Recangle*r){returnr;}//返回指针Rectangle&h(Rectangle&r){returnr;}//返回引用函数f()返回对象r的值,这要产生一个匿名临时常量对象g()返回对象的指针,也就是返回对象的地址,不会引起构造函数的调用h()返回对象的引用,就是返回对象本身,可以作为左值使用。需要注意的是,在函数返回对象指针或引用时,被指向或被引用的对象必须具有超出函数作用域的生命期。例函数:Rectangle&f(Rectangler){returnr;}会出现什么问题?6.6.3常量对象const关键字可以约束普通变量,也可以约束一个对象,使之成为常量对象。例如:constRectanglerect(3,4);这样一来,对象rect的所有属性都是不可修改的,除非某个属性被说明成是mutable常量对象的两种使用情形:函数返回对象的值这一情况。这个返回的对象被编译器自动约束成为常量对象常量对象作为函数的参数与无约束对象一样,可以调用常量对象的成员函数来完成某项操作。但这可能带来潜在的错误:这个成员函数可能会修改对象的属性易变的常对象不能被更新参见例子7_9.cpp,7_10.cpp6.6.4常成员函数类的某些成员函数只是读取属性而不修改它们。这样,可以将这样的成员说明成是常成员。例如:classRectangle//简化版{private: int width,height; //othermemberspublic: doublearea()const{returnwidth*height;}};关键字const将成员函数area()的this指针和它指向的对象约束成为常量,因此在其内部任何试图改变对象状态的操作都是非法的。在常成员函数中不能调用非常成员函数,因为那些函数有可能改变对象的状态。如果在类内声明常成员函数而在类外定义它,那么二者的声明必须完全一致。例如:classRectangle//简化版{private: int width,height; //othermemberspublic: doublearea()const;};

doubleRectangle::area()const

{returnwidth*height;}参见例子7_11.cpp6.6.5嵌套类如果类A只为类B提供服务,那么A最好成为B的内部类。这里,类A称为类B的“嵌套类(nestedclass)”,而类B是类A的“包围类”。1.嵌套类的定义classRectangle{public: stringname;

structSize { intwidth,height; voidshow(); }cxy;};6.6与类和对象相关的问题2.在包围类外使用嵌套类需要名字限定嵌套类的名字完全局部于它的包围类,而它的作用域也被局限在包围类的作用域中。这样一来,嵌套类对包围类以外来说是不可见的,因此在包围类外直接使用嵌套类的名字是不合法的。下面的代码是错误的:voidf(){ Sizesize={10,20};//错误,在Rectangle外Size是不可见的}如果一定要在包围类外使用嵌套类的名字,或者定义嵌套类的成员,那么必须使用名字限定。例如:voidf(){

Rectangle::Sizesize={10,20};//OK}6.6与类和对象相关的问题3.包围类的成员对嵌套类是不可见的嵌套类形成了一个局部作用域,包围类的成员在这个作用域中是不可见的。下面的show()定义是错误的:voidRectangle::Size::show()//OK,正确的名字限定{

cout<<name<<':'<<width<<','<<height<<endl;//错误,name等包围类的成员对Size来说是不可见的}6.6与类和对象相关的问题4.嵌套类的声明和定义可以分开如果嵌套类的代码比较长,那么可以采用这样的方式来进行:在包围类中声明嵌套类,然后在包围类之外定义嵌套类。例如:classRectangle{public: stringname;

structSize;//类的超前声明};

structRectangle::Size{…};//注意使用名字限定6.6与类和对象相关的问题5.嵌套类中的友元可以在嵌套类中声明它的友元。例如:classRectangle{public: structSize {

friendvoidshow(); }cxy;};不过,全局函数show()只是类Size的友元,而非包围类Rectangle的。因此,show()函数没有获得特殊的权限访问包围类Rectangle的成员。6.6.6类中定义类型1.在类中定义枚举类型classQuadrangle{public: enumID{RECTANGLE,SQUARE,DIAMOND}; …};这样,类型ID被限制在包围类Quadrangle的作用域中6.6与类和对象相关的问题类中的枚举成员不属于对象,而是该类的所有对象共享的。因此,对枚举成员的访问必须采用名字限定的方式进行。例如:

Quadrangle::IDid=Quadrangle::RECTANGLE;//OKid=SQUARE;//error同样地,如果枚举定义被放在非公有段中,以上访问如果发生在Quadrangle类之外就是非法的。6.6与类和对象相关的问题2.类中的typedef可以在类中用typedef为已有的类型取一个别名。例如:classQuadrangle{public:

typedefenumID{RECTANGLE,SQUARE,DIAMOND}QUADID;};与类中的其它名字一样,别名QUADID也被局限在包

温馨提示

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

评论

0/150

提交评论