![C++课件 第14章 构造函数_第1页](http://file3.renrendoc.com/fileroot_temp3/2022-1/28/92b18904-f341-4f04-9450-49a9ec642490/92b18904-f341-4f04-9450-49a9ec6424901.gif)
![C++课件 第14章 构造函数_第2页](http://file3.renrendoc.com/fileroot_temp3/2022-1/28/92b18904-f341-4f04-9450-49a9ec642490/92b18904-f341-4f04-9450-49a9ec6424902.gif)
![C++课件 第14章 构造函数_第3页](http://file3.renrendoc.com/fileroot_temp3/2022-1/28/92b18904-f341-4f04-9450-49a9ec642490/92b18904-f341-4f04-9450-49a9ec6424903.gif)
![C++课件 第14章 构造函数_第4页](http://file3.renrendoc.com/fileroot_temp3/2022-1/28/92b18904-f341-4f04-9450-49a9ec642490/92b18904-f341-4f04-9450-49a9ec6424904.gif)
![C++课件 第14章 构造函数_第5页](http://file3.renrendoc.com/fileroot_temp3/2022-1/28/92b18904-f341-4f04-9450-49a9ec642490/92b18904-f341-4f04-9450-49a9ec6424905.gif)
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、第十四章 构造函数 面向对象语言的构造函数是很重要的,它涉及到对象的构造及效率,但构造函数又很复杂。在JAVA语言和本门课前面的内容中,以及很多编程书中,为突出构造函数的基本概念和基本特性,有意的忽略了构造函数的复杂性。现在,在类、继承、多态讲完后,作为单独的一章,集中讲一下C+的构造函数,为了有连续性,其中有一些内容与课件前面 “基于对象/面向对象” 相关章节(5,6,9,10章)的内容重复。课件前面有关构造函数讲的比较模糊的地方,与本章课件为准。虽然讲的是C+的构造函数,但其中一部分内容对其它面向对象的语言(包括JAVA)也有参考价值。本章内容包括:n 单个类的构造函数;n 继承方式下子类
2、的构造函数;一、单个类的构造函数;1一般特性 构造函数的作用是创建对象,进行对象的内存分配、初始化成员变量等工作。析构函数的作用与构造函数相反。C+构造函数主要特点:l 构造函数的名字与类名相同l 构造函数也是成员函数,声明在类体内,实现在类体外或在类体内。l 构造函数无需声明返回类型和返回值(有系统内部使用的隐含返回值)。l 构造函数可以重载。l 当类没有定义构造函数时,系统默认一个。C+析构函数特点:l 析构函数的名字是在类名前加l 析构函数也是成员函数,声明在类体内,实现在类体外或在类体内。l 析构函数无需声明返回类型和返回值,也无需形参。l 析构函数不可以重载,一个类只能有一个析构函数
3、。l 当类没有定义析构函数时,系统默认一个。2. 默认的构造函数 Q1:当类没有定义构造函数时,系统默认一个。注本章所有程序均在VC8.0下调试例1: #include "stdafx.h"#include "iostream"using namespace std;class Apublic: unsigned short int i;int _tmain(int argc, _TCHAR* argv) A a1; cout<<a1.i; cout<<a1.i输出了一个随意指定的整数,说明对象a1被默认的构造函数创建了,但这个程
4、序在编译的时侯告警,运行时报错,按“确定”后才输出正确结果。为什么会这样?把程序改一下:例2:以下程序在VC8.0下调试#include "stdafx.h"#include "iostream"using namespace std;class Apublic: unsigned short int i; virtual int fun()return 1; /增加了一个虚函数 ;int _tmain(int argc, _TCHAR* argv) /不能写成A(a1),/但可写成A* a1=new A()或A* a1=new AA a1; cout&
5、lt;<a1.i; 运行正常。原来,很多C+书说错了,“当类没有定义构造函数时,系统默认一个”是有先决条件的:如果一个类中没有定义任何的构造函数,那么编译器只有在以下三种情况,默认的构造函数才会正确工作:( 1)如果类有虚拟成员函数或者虚拟继承父类(即有虚拟基类)时;( 2)如果类的基类有构造函数(可以是用户定义的构造函数,或编译器提供的默认构造函数); ( 3)在类中的所有非静态的对象数据成员,它们所属的类中有构造函数(可以是用户定义的构造函数,或编译器提供的默认构造函数)。记住上述几条有点费劲,所以,我们还是自已写一个构造函数好,而一般不要用系
6、统默认的。Q2:当自已写一个构造函数时,无论有参和无参,默认构造函数均无效例3:#include "stdafx.h"#include "iostream"using namespace std;class Apublic: int i; virtual int fun()return 1; A()i=1;cout <<"构造函数1被执行" A(int x)i=x;cout <<"构造函数2被执行"int _tmain(int argc, _TCHAR* argv) A a1; cout&l
7、t;<a1.i; A a2; cout<<a2.i; A a3(2); cout<<a3.i; 结论是对的,构造函数A()被执行了两次。Q3:为什么用系统默认或无参构造函数实例化栈对象时,不能用A a1(),只能用A a的语法?例4:#include "stdafx.h"#include "iostream"using namespace std;class Apublic: int i; virtual int fun()return 1; A()i=1;cout <<"构造函数1被执行"
8、A(int x)i=x;cout <<"构造函数2被执行"int _tmain(int argc, _TCHAR* argv) A* a4=new A();/正确A* a5=new A; /正确A a6();/创建栈对象,应写为A a6 原因是:A a6()这种写法,编译器会误以为它是个无参的函数声明,返回类型为A。所以,用系统默认或无参构造函数创建栈对象时,只能用A a6这种写法。Q4 类体内(类的声明部分)不允许初始化成员变量,初始化成员变量是构造函数要做的事(这一部分与课件第六章基本重复,以本章为准)。例5:class Tpublic: int=1; /这
9、是不允许的 ;这样的规定是合乎面向对象思想的,类是一个“数据类型”的抽象,类成员有具体值的时侯就变成一个对象了。创建对象的分工给构造函数去做比较好。下面的例子哪里有错?例6:(课件第6章Q6有这个例子)class Aprivate:int i = 0; / 错,成员变量不能在类体内初始化const int a = 1; / 错 static int b = 2; / 错 static const int c =3; /错. ?;static const int c =3是对的。C+标准关于static数据成员在类中声明的描述是:static数据成员在类声明中声明,在包含类方法的文件中初始化。但
10、如果static成员是整型或枚举型const,则可以在类声明中初始化,这是一种例外,不敢保证所有编译器都能通过(VC8能通过) 作为通用原则,const, static成员变量的初始化只能用两种方法:(1)一种方式就是在外部初始化,只适合于static或static const(非static变量不能外部初始化)。原因大概是static变量是属于类的,多个对象共享一个static变量,它在创建对象(调用构造函数)之前就因该存在,否则不能用 类名. static变量名访问,而且多次构造会破坏static变量的值。(2)用构造函数初始化列表。适合于const和一般变量(稍后解释),不适合stati
11、c(原因同上)。例7:class Apublic: const int a; static int b;const static int c; const static float d; A():a(1)cout<<"OK"<<endl; /初始化列表初始化a; int A:b = 2; /外部初始化b,前面不允许写static const int A:c=3; /外部初始化c,前面不允许写static const float A:d=4.5; /外部初始化d,前面不允许写staticint _tmain(int argc, _TCHAR* argv
12、) A a4; A* a5=new A(); cout<<a4.a<<a4.b<<a4.c<<a4.d<<endl; cout<<a5->a<<a5->b<<a5->c<<a5->d<<endl;上例中,const static int c;可写成const static int c=3;去掉const int A:c=3;Q5:什么是初始化列表?(这一部分与课件第六章基本重复,以本章为准)初始化列表又叫构造函数初始化列表,它是一个特殊的构造函数,可以
13、对类的成员变量(或常量)初始化。其语法为:类名():变量1(表达式),变量2(表达式)例如:class CExample public: int a; float b;/构造函数初始化列表,也可以写到类体外 Cexample(): a(0),b(8.8) /这里可以写构造函数体,也可以什么也不写 /构造函数内部赋值进行初始化,该函数也可写到类体外
14、160;Cexample() a=0; b=8.8; 上面的例子中两个构造函数的结果是一样的。只是前者显式的初始化类的成员,后者没有进行显式的初始化。但两者有很明显的区别:初始化列表在构造函数主体执行前就执行了,这不仅可以提高效率(有的书声称做过实验,使用初始化列表创建对象的速度比使用赋值构造函数快1/3),更重要的是,适合于继承条件下子类的初始化。对于C+内置的数据类型(int,数组等),初始化列表和一般的构
15、造函数赋值没有区别。对引用类型成员变量(比如说对象),为了避免多次构造,一般要使用构造函数初始化列表。对于const,必须使用构造函数初始化列表,原因一是const是被类的每个对象独享的(一个对象的const成员只有一个值,但不同对象的const可能会有不同值,),只能在构造函数中初始化;而一般构造函数的赋值语句不能初始化const(我们知道,常量只能在声明的时侯赋值,这种赋值应该叫初始化),所以不能用一般的构造函数进行赋值,只能用构造函数初始化列表。最后,是初始化列表的执行顺序:它是按声明顺序进行的,比如:class CExample public:
16、; int a; float b;/构造函数初始化列表,也可以写到类体外 Cexample(): b(8.8) ,a(0) /这里可以写构造函数体,也可以什么也不写 ;先初始化a,因为a声明在先。Q6:拷贝初始化构造函数 在课件第五章讲过,在JAVA中也学过没有什么变化,不再重复。我们应该对对象的深拷贝(传值)和浅拷贝(传引用)的概念很清楚。最常用的就是将对象作为函数的参数,如果不想更改原对象的状态就用深拷贝,否则浅
17、拷贝。 二、继承方式下子类的构造函数(这一部分与课件第九章基本重复,以本章为准); 当一个派生类对象被创建时,其基类对象也被创建,实际上一个派生类对象是由其基类对象和派生类对象“组装”而成,了解这一点才能了解派生类 构造函数/析构函数 的有关特性。这一系列的创建过程是用构造函数初始化列表完成的。1. 派生类的构造函数构造函数不能够被继承,因此,派生类的构造函数必须通过调用基类的构造函数来初始化派生类对象。所以,在定义派生类的构造函数时除了对自己的数据成员进行初始化外,还必须负责调用基类构造函数使基类数据成员得以初始化。如果派生类中还有子对象时(比如将某个类的对象作为派生类的成员变量),还应包含
18、对子对象初始化的构造函数。派生类构造函数的一般格式如下(使用构造函数初始化列表):派生类名(派生类构造函数总参数表):基类构造函数(参数表1),子对象名(参数表2) /派生类中数据成员初始化;派生类构造函数的调用顺序如下:l 基类的构造函数l 子对象类的构造函数(如果有的话)l 派生类构造函数Q1:下面程序的运行结果:class A private:int a;public: A() a=0;cout<<"Ad" /缺省构造函数 A(int i) a=i; cout<<"A" /构造函数 ;class B:public Aprivate:int b; A aa; /子对象aapublic:B() b=0;cout<<"Bd"<<endl; /缺省构造函数 B(int i, int j, int k);
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 北湖小学数学试卷
- 2025年度国际教育培训机构合作合同-@-5
- 2025年度综合施工作业吊车租赁包月合同
- 《线段、直线、射线》说课稿-2024-2025学年四年级上册数学人教版
- 数学一年级听评课记录
- 现代企业中的跨部门团队协作模式探讨
- 电动交通工具在办公环境中的应用案例
- 2025年度网红直播户外广告合作合同(HBF-RH)
- 2025年度航空客运航班延误补偿合同
- 电商物流的包装与回收利用策略
- 小学校本课程教材《趣味数学》
- 干细胞疗法推广方案
- (2024年)电工安全培训(新编)课件
- mil-std-1916抽样标准(中文版)
- 《社区康复》课件-第七章 脑瘫患儿的社区康复实践
- 城乡环卫一体化内部管理制度
- 广汇煤炭清洁炼化有限责任公司1000万吨年煤炭分级提质综合利用项目变更环境影响报告书
- 小学数学六年级解方程练习300题及答案
- 大数据在化工行业中的应用与创新
- 光伏十林业可行性报告
- 小学综合实践《我做环保宣传员 保护环境人人有责》
评论
0/150
提交评论