《c++课件,从零开始》由会员分享,可在线阅读,更多相关《c++课件,从零开始(29页珍藏版)》请在金锄头文库上搜索。
1、C+程序设计教程(第二版)第九章 对象生灭 Chapter 9 Object Birth month=m; day=d; n void print( ) n coutDate e对象创建的运行顺序为:Date eDate12同一工程不同代码文件全局对象的创建 没有明确顺序规定 对策:不要让不同文件的全局对象互为 依赖因为依赖具有先后性,而其全 局对象的创建不能保证该依赖性发挥 作用 全局对象在main函数启动之前生成,而 调试则在main函数启动之后对策:调试时,应先将全局对象作为局 部对象来运行观察或者,在构造函 数中添加输出语句来观察运行过程Date13成员对象的构造顺序按类中定义 的出现
2、顺序,最后执行自身构 造函数:class AB b;C c;D d;public:A()/ .;int main()A a;则构造顺序为bcd,然后执行A 的构造函数的花括号体Date14全局数据区: 全局对象,静态全局对象,静态局部对象,常对象 存放在该数据区栈区: 局部对象 (根据不同编译器的实现方法,临时对象可能在 栈区,也可能在动态存储区,也可能一部分 在栈区,一部分在动态存储区)动态存储区(也称堆区): 用new申请的对象除此之外,还可以指定特殊地址空间,存放对 象构造位置Date155. 拷贝构造函数 ( Copy Constructors ) 对象本体与对象实体: 对象本体也是对
3、象主体,对象实体 则还包括属于对象的衍生物,如 ,某个人体是人类对象的主体, 然而某人还拥有父母,房产等属 于某人的世系或资产,描述人的 属性不仅仅只是人体数据 从形式上看,对象除了包括数据成 员,还包括指向数据的指针Date16拷贝构造函数n拷贝初始化构造函数是一种特殊的成 员函数,其形参是本类对象的引用。 它的功能是用一个已知的对象来初始 化一个被创建的同类的对象n拷贝初始化构造函数实际上也是构造 函数,它是在初始化时被调用来将一 个已知对象的数据成员的值拷贝给正 在创建的另一个同类的对象。Date17其特点如下:n1. 该该函数名同类类名,并且该该函数也不被指 定返回类类型。n2. 该该
4、函数只有一个参数,并且是对对某个对对 象的引用。n3. 每个类类都有各自的拷贝贝初始化构造函数, 其格式如下所示:n:( Date(const Date/ . . . ;Date x; /调用无参构造函数 Date y(x); /调用拷贝构造函数Date19默认拷贝构造函数:若类中没有定义拷贝构造函数,则系统会 悄悄定义一个默认空拷贝构造函数:Date(const Date public:Person(char* pN=“noName“)pName = new charstrlen(pN)+1;if(pName) strcpy(pName,pN);Person(const Personif(p
5、Name) strcpy(pName, s.pName);Person()delete pName; ;Date216. 析构函数 ( Destructors )对象结束其生命时,会被系统 悄悄地销毁(析构).即对象 本体空间与名字脱离关系.对象结束生命时,若对象本体 与对象实体不同,则需要人 为地进行资源释放,以保证 对象本体失效之前,资源被 收回Date22定义析构函数的目的:由于对象本体与实体不同,所以要进 行对象占有资源的释放工作 一般来说,一个类,若有人为定义的 拷贝构造函数,则也应该定义析构 函数因为对象创建中有资源要获 得分配,则对象失效前必应先释放 资源Date23析构函数的特
6、点: 析构函数也是成员员函数,函数体可写在类类体 内,也可以写在内体外。 析构函数的名字同类名,并在前面加“”字符 ,用来与构造函数加以区别。析构函数不指 定数据类型,并且也没有参数。 一个类中只可能定义一个析构函数,不能重 载。Date24n4. 析构函数可以被调调用,也可以系统统自 动调动调 用,在下面两种情况,析构函数会被 自动调动调 用:如果一个对象被定义在一个函数体内,则当这个函数结束时,该对象的析构函数 被自动调用。 n当一个对象是用new运算符被动态创建 的,在使用delete运算符释放它时, delete会自动调用析构函数。n5. 如果用户户没有编编写析构函数,编译编译 系 统
7、统会自动动生成一个缺省的析构函数。 Date257. 转型与赋值 ( Conversion / .;void fn(Studentint main()string t=“jenny”;fn(t); / 参数为string,却能匹配Student类 型Date26对象转型的规则:n只会尝试含有一个参数的构造函数n如果有二义性,则会放弃尝试n推导是一次性的,不允许多步推导fn(“Jenny”)不能匹配void fn(const Student因为:”Jenny” - string- Student经历了两步.Date27对象赋值即对象拷贝:两个已经存在 的对象之间的复制Person d, g;d
8、= g; / 对象赋值 对象赋值便是使用类中的赋值操作符 如果类中没有定义赋值操作符,则系 统悄悄地定义一个默认的赋值操作 符:PersonDate28当对象本体与对象实体不同时, 则对象赋值操作符与拷贝构造 函数一样,必须自定义:class Personchar* pName; public:Person(char* pN=“noName“);Person(const PersonPersondelete pName;pName = new charstrlen(s.pName)+1;if(pName) strcpy(pName,s.pName);return *this;Person()delete pName; ;定义赋值操作符 :排除客体对象 与本对象同 一的情况 释放本对象的 资源 申请客体对象 相同大小的 资源空间 拷贝客体对象 的资源到本 对象Date29