《C++程序设计教程9.ppt》由会员分享,可在线阅读,更多相关《C++程序设计教程9.ppt(22页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、15:12:011C+程序设计教程(第二版)第九章 对象生灭 Chapter 9 Object Birth&Death 清华大学出版社 钱 能15:12:012第九章内容1.构造函数设计构造函数设计(Constructor Design)2.构造函数重载构造函数重载(Constructor Overload)3.类成员初始化类成员初始化(Class Member Initializations)4.构造顺序构造顺序(Constructing Order)5.拷贝构造函数拷贝构造函数(Copy Constructors)6.析构函数析构函数(Destructors)7.转型与赋值转型与赋值(Co
2、nversion&Assignment)15:12:0131.构造函数设计构造函数设计(Constructor Design)初始化要求:对象与变量的不同在于对象对应于事物,要求从诞生之时起便有明确的意义.封装性要求:初始化不是简单的参数与成员对应,而是联系参数到成员的过程.构造函数名:该过程产生对象,而不是捆绑对象的成员函数调用,因而它是特殊的成员函数形式:与变量的定义形式保持一致.构造函数原则上不能失败,也没有返回形式例外:一次性对象构造,没有对象名,与强制转换的形式一致,因而它是一个特定类型的对象.15:12:0242.构造函数重载构造函数重载(Constructor Overload)
3、构造函数可以重载,也可以参数默认:class Datepublic:Date(const string&s);Date(int y=2003,int m=12,int d=1);/.;int main()Date d(“2006-12-26”);Date e(2000,12,25);Date f(2001,10);Date g(2002);Date h();/.15:12:025若类中没有定义构造函数,则系统会默认定义一个无参空函数:class Datepublic:/相当于定义了Date();int main()Date d;/ok /.15:12:026任何其他的构造函数定义,都将阻止默认
4、无参空函数的产生:class Datepublic:Date(int y,int m,int d)/.;int main()Date d;/error /.15:12:0273.类成员初始化类成员初始化(Class Member Initializations)class StudentID int a;public:StudentID()a=1;cout“StudentId:an;class Student string name;StudentID id;public:Student(string n=noName)cout“Student:+n+n;name=n;int main()St
5、udent s(Randy);数据成员的空间分配是在构造函数被调用和其过程被执行之间的刹那间完成,在类中有对象成员时,那个刹那间便是调用对象所在类的构造函数,以创建对象空间的时机,左边的程序得到下列运行结果:StudentId:1Student:Randy说明先成员构造,后自身构造成员构造不见显式调用,而是悄悄调用无参构造函数15:12:028class StudentID int a;public:StudentID(int id=0)a=id;cout“StudentId:a“n”;class Student string name;StudentID id;public:Student(
6、string n=noName,int ssID=0):id(ssID),name(n)cout“Student:nDate e 对象创建的运行顺序为:Date e15:12:0210同一工程不同代码文件全局对象的创建没有明确顺序规定对策:不要让不同文件的全局对象互为依赖因为依赖具有先后性,而其全局对象的创建不能保证该依赖性发挥作用全局对象在main函数启动之前生成,而调试则在main函数启动之后对策:调试时,应先将全局对象作为局部对象来运行观察或者,在构造函数中添加输出语句来观察运行过程15:12:0211成员对象的构造顺序按类定义的出现顺序,最后执行自身构造函数:class A B b;C
7、 c;D d;public:A()/.;int main()A a;则构造顺序为bcd,然后执行A的构造函数的花括号体15:12:0212全局数据区:全局对象,静态全局对象,静态局部对象,常对象类的静态数据成员也存放在该数据区栈区:局部对象(根据不同编译器的实现方法,临时对象可能在栈区,也可能在动态存储区,也可能一部分在栈区,一部分在动态存储区)动态存储区(也称堆区):用new申请的对象除此之外,还可以指定特殊地址空间,存放对象构造位置15:12:02135.拷贝构造函数拷贝构造函数(Copy Constructors)对象本体与对象实体:对象本体也是对象主体,对象实体则还包括属于对象的衍生物
8、,如,某个人体是人类对象的主体,然而某人还拥有父母,房产等属于某人的世系或资产,描述人的属性不仅仅只是人体数据从形式上看,对象除了包括数据成员,还包括指向数据的指针15:12:0214拷贝构造函数:以本类对象为常量引用参数的构造函数:class Datepublic:Date();Date(const Date&d);/.;Date x;/调用无参构造函数Date y(x);/调用拷贝构造函数15:12:0215默认拷贝构造函数:若类中没有定义拷贝构造函数,则系统会悄悄定义一个默认空拷贝构造函数:Date(const Date&d)默认拷贝构造函数体一定是空的空拷贝构造函数负责将传递的对象到新
9、创的对象做对象本体的位对位拷贝(甚至连指针值都相等,即与参数对象拥有共同的资源)拷贝构造函数体的工作不负责位对位对象复制,一般来说,它负责资源分配和由此而来的指针修改15:12:0216拷贝构造函数体的工作不负责位对位对象复制,一般来说,它负责资源分配和由此而来的指针修改class Person char*pName;public:Person(char*pN=noName)pName=new charstrlen(pN)+1;if(pName)strcpy(pName,pN);Person(const Person&s)pName=new charstrlen(s.pName)+1;if(p
10、Name)strcpy(pName,s.pName);Person()delete pName;15:12:02176.析构函数析构函数(Destructors)对象结束其生命时,会被系统悄悄地销毁(析构).即对象本体空间与名字脱离关系.对象结束生命时,若对象本体与对象实体不同,则需要人为地进行资源释放,以保证对象本体失效之前,资源被收回15:12:0218定义析构函数的目的:定义析构函数的目的:由于对象本体与实体不同,所以要进由于对象本体与实体不同,所以要进行对象占有资源的释放工作行对象占有资源的释放工作一般来说,一个类,若有人为定义的一般来说,一个类,若有人为定义的拷贝构造函数,则也应该定
11、义析构拷贝构造函数,则也应该定义析构函数因为对象创建中有资源要获函数因为对象创建中有资源要获得分配,则对象失效前必应先释放得分配,则对象失效前必应先释放资源资源15:12:02197.转型与赋值转型与赋值(Conversion&Assignment)对象转型一个构造函数,含有一个其他数据类型的参数,显然其意义为,用该参数类型的值可以创建本对象.从另一方面看,参数类型的值可以转换为本对象.class Student public:Student(const string&n);/.;void fn(Student&s);int main()string t=“jenny”;fn(t);/参数为s
12、tring,却能匹配Student类型 15:12:0220对象转型的规则:n只会尝试含有一个参数的构造函数只会尝试含有一个参数的构造函数n如果有二义性,则会放弃尝试如果有二义性,则会放弃尝试n推导是一次性的,不允许多步推导推导是一次性的,不允许多步推导 fn(“Jenny”)不能匹配不能匹配 void fn(const Student&s);因为:因为:”Jenny”-string -Student 经历了两步经历了两步.15:12:0221对象赋值即对象拷贝:两个已经存在的对象之间的复制Person d,g;d=g;/对象赋值对象赋值便是使用类中的赋值操作符如果类中没有定义赋值操作符,则系
13、统悄悄地定义一个默认的赋值操作符:Person&operator=(const Person&p)memcpy(*this,*p,sizeof(p);15:12:0222当对象本体与对象实体不同时,则对象赋值操作符与拷贝构造函数一样,必须自定义:class Person char*pName;public:Person(char*pN=noName);Person(const Person&s);Person&operator=(const Person&s)if(this=&s)return s;delete pName;pName=new charstrlen(s.pName)+1;if(pName)strcpy(pName,s.pName);return*this;Person()delete pName;定义赋值操作符:排除客体对象与本对象同一的情况释放本对象的资源申请客体对象相同大小的资源空间拷贝客体对象的资源到本对象
限制150内