第12章 构造函数_第1页
第12章 构造函数_第2页
第12章 构造函数_第3页
第12章 构造函数_第4页
第12章 构造函数_第5页
已阅读5页,还剩51页未读 继续免费阅读

下载本文档

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

文档简介

1、第12章 构造函数2本章主要内容o12.1 类与对象o12.2 构造函数的需要性o12.3 构造函数的使用o12.4 析构函数o12.5 带参数的构造函数o12.6 重载构造函数o12.7 默认构造函数o12.8 类成员初始化的困惑o12.9 构造类成员o12.10 构造对象的顺序o作业312.1 类与对象1. 类与对象的区别o类:抽象的,描述一类事物应具有的属性和操作。o对象:具体的,是类的一个具体的实例,具有确定的属性和操作。o对象可以被创建和销毁,但类是无所不在的。2.对象的定义o定义对象应为对象分配内存空间。o在11.4节中已介绍412.1 类与对象3.对象的初始化o初始化要求:对象的

2、定义表达了现实世界的实初始化要求:对象的定义表达了现实世界的实体体, ,因此因此, ,一旦建立一个类的对象一旦建立一个类的对象, ,需要一个有意需要一个有意义的初始值义的初始值。所以类的对象创建的时候必须被。所以类的对象创建的时候必须被初始化。初始化。Student t; /全局对象全局对象int main() Student s; /局部对象局部对象 /说明:说明:全局对象全局对象, ,静态对象以全静态对象以全0 0位的模式表示,位的模式表示, 局部对象以随机值表示。局部对象以随机值表示。512.2 构造函数的需要性o变量初始化的方法如下: int a=1; int * pa=&a;

3、o数组初始化的方法如下: int b =1,2,3,4;o结构初始化的方法如下: struct Student int somesHours; /总需学时数 float gpa; /平均成绩 ; void fn( ) Student s=100, 3.5; /创建结构变量时初始化 / 612.2 构造函数的需要性o封装性要求:封装性要求:初始化不是简单的参数与成员对应初始化不是简单的参数与成员对应, ,而是而是联系参数到成员的过程联系参数到成员的过程. .class Student protected: int somesHours; /总需学时数 float gpa; /平均成绩 ; voi

4、d fn( ) Student s=100, 3.5; /error,不能访问;/因为类的封装性, 相当于可以访问类的保护成员 / ;o说明:类对象不能使用和结构类似的初始化方式;应该通过成员函数初始化。712.2 构造函数的需要性o普通的成员函数初始化对象class Student public: void init()somesHours=100; gpa=3.5; protected: int somesHours; /总需学时数 float gpa; /平均成绩 ; void fn( ) Student s; s.init(); /增加书写代码,且不能真正实现初始化 ;o说明:应该通过

5、特殊的成员函数初始化对象,即构造函数。8o构造函数:在类定义中,与类同名且没有返回类型的成员函数。o作用:在创建对象时,由系统自动调用,对对象进行初始化 。12.3 构造函数的使用9o1.构造函数创建构造函数创建 class Pointdouble x , y ;public:Point(double ix , double iy) /构造函数构造函数 x=ix; y=iy; double xOffset();double yOffset();double angle();double radius(); 12.3 构造函数的使用10int main( )Point p1(3,4); 自动调用

6、构造函数自动调用构造函数Point(double ix , double iy); 12.3 构造函数的使用11o构造函数可以放在类的外部定义,加“类名:”。o例:/ch12_1.cpp #include class Desk public: Desk( ); /构造函数声明 protected: int weight; int high; int width; int length; ;12.3 构造函数的使用class Stool public: Stool( ); /构造函数声明 protected: int weight; int high; int width; int length

7、; ;12Desk:Desk( ) /构造函数定义 weight=10; high=5; width=5; length=5; cout weight high width length endl; Page 12Stool:Stool( ) /构造函数定义 weight=6; high=3; width=3; length=3; cout weight high width length endl; 12.3 构造函数的使用13 void fn( ) Desk da; /自动调用Desk( ) Stool sa; /自动调用Stool( ) int main( ) fn( ); 主函数运行时

8、调用主函数运行时调用fn( ), fn( )fn( ), fn( )在创建在创建DeskDesk对象对象dada和和StoolStool对象对象sasa时,分别调用了两者的构造函数。时,分别调用了两者的构造函数。12.3 构造函数的使用运行结果:运行结果:10 5 5 56 3 3 314o如果在上例中的函数如果在上例中的函数fn( )中,定义桌子对象的语中,定义桌子对象的语句改成定义句改成定义对象数组对象数组:Page 14void fn( ) Desk dd 5 ; /对象数组dd Stool sa ; 则定义则定义对象数组对象数组的语句中构造函数会被调用的语句中构造函数会被调用5次。次。

9、12.3 构造函数的使用运行结果:运行结果:10 5 5 510 5 5 510 5 5 510 5 5 510 5 5 56 3 3 315o2.构造函数的特点o构造函数与类同名,没有返回类型,函数体中不允许返回值,但可以有无值返回语句 “return;”;由系统自动调用。o例: void Desk:Desk( ) /error:构造函数定义class Pointdouble x , y ;public:Point(double ix , double iy) if(ix0 | iy0) cout“illegle date!n”; return; /. ;Page 1512.3 构造函数的使

10、用16o3.对象成员的构造o一个类定义中 ,类的数据成员可能为另一个类的对象, 此时在类的对象创建所调用的构造函数中,对该成员(对象)自动调用其构造函数。o例: /ch12_2.cppo #include o class Studento public:o Student( ) o cout constructing student.n;o semesHours=100;o gpa=3.5;o o /其他公共成员 o protected:o int semesHours;o float gpa;1. ;l class Teacherl public:l Teacher( ) l cout co

11、nstructing teacher.n;l l ; 12.3 构造函数的使用17oclass TutorPairo public:o TutorPair( ) o cout constructing tutorpair.n;o noMeetings=0;o o protected:o Student student;o Teacher teacher;o int noMeetings; /会晤次数o;oint main( ) o TutorPair tp;o cout back in main.n;o 运行结果为:运行结果为:constructing student.constructing

12、 teacher.constructing tutorpair.back in main.12.3 构造函数的使用1812.4 析构函数o 对象结束其生命时,会被系统悄悄地销毁(析构),即对象本体空间与名字脱离关系。o析构函数:在类定义中,与类同名、并在前面冠以“”的成员函数 。o特点:是特殊的类成员函数,它没有返回类型,没有参数,不能随意调用,系统自动调用,也没有重载。o作用:释放对象在构造中分配的资源(例如:关闭被构造函数打开的文件,释放动态内存)。在对象生命期结束时,由系统自动调用,并且以与构造函数相反的调用顺序被调用。19o#include oclass Studento public

13、:o Student( )o cout constructing student.n;o semesHours=100;o gpa=3.5;o o Student( )o cout destructing student.n;o /其他公共成员 protected: int semesHours; float gpa; ; class Teacher public: Teacher( ) cout constructing teacher.n; Teacher( ) cout destructing teacher.n; ;/ch12_3.cpp20oclass TutorPairo publ

14、ic:o TutorPair( )o cout constructing tutorpair.n;o noMeetings=0;o o TutorPair( )o cout destructing tutorpair.n;o protected:o Student student;o Teacher teacher;o int noMeetings;o;o int main( )o o TutorPair tp;o cout back in main.n;o 运行结果:运行结果: constructing student. constructing teacher. constructing

15、tutorpair. back in main. destructing tutorpair. destructing teacher. destructing student. 注意:构造函数和析构函数的调用顺序正好相反。2112.5 带参数的构造函数o不带参数的构造函数对数据成员的初始化,取决于构造函数体中对哪些数据成员进行赋初值,且用此构造函数构造的所有对象的初始值都相同。 o带参数的构造函数可以使得各对象的数据成员的初始值不同,通过创建对象时将实参传递给构造函数,达到初始化目的。Page 2122/ch12_4.cppo# includeo# includeoclass Student

16、o public:o Student(char* pName)o cout constructing student pName endl; o strncpy(name,pName,sizeof(name); /字符串复制o namesizeof(name)-1=0;o o Student( )o cout destructing name endl;o /其他公共成员12.5 带参数的构造函数23o构造函数可以有任意多个参数。/ch12_5.cpp o # include o # include o class Studento public:o Student(char* pName,

17、int xHours, float xgpa) o cout constructing student pName endl;o strncpy(name,pName,sizeof(name);o namesizeof(name)-1=0;o semesHours=xHours;o gpa=xgpa;o o Student( )o cout destructing name endl;o o /其他公共成员o protected:o char name20;o int semesHours;o float gpa;o ; o int main( )o Student ss(Jenny, 22,

18、 3.5);o 运行结果为:运行结果为:constructing student Jennydestructing Jenny2412.6 重载构造函数o重载构造函数:在一个类中出现多个构造函数,但是它们所带的参数个数、参数类型,或次序有所不同 。/ch12_6.cppo # include o class Tdateo public:o Tdate( ); /默认构造函数o Tdate(int d);o Tdate(int m, int d);o Tdate(int m, int d, int y);o /其他公共成员o protected:o int month;o int day;o i

19、nt year;1. ;Page 2425oTdate:Tdate( ) o month=4; day=15; year=1995;o cout month / day /year endl;ooTdate:Tdate(int d)o month=4; day=d; year=1996;o cout month / day/ year endl;ooTdate:Tdate(int m, int d)o month=m; day=d; year=1997;o cout month / day/ year endl;o oTdate:Tdate(int m,int d, int y)o month

20、=m; day=d; year=y;o cout month / day/ year endl;o12.6 重载构造函数 int main( ) Tdate aday; Tdate bday(10); Tdate cday(2, 12); Tdate dday(1, 2, 1998); 运行结果:运行结果:4/15/19954/10/1996 2/12/19971/2/199826o多个构造函数可以共享初始化过程,先定义一个共享成员函数,然后每个构造函数都调用之。/ch12_7.cppo# include oclass Tdateo public:o Tdate( ) Init(4,15,19

21、95); o Tdate(int d) Init(4,d,1996); o Tdate(int m,int d) Init(m,d,1997); o Tdate(int m,int d,int y) Init(m,d,y); o /其他公共成员o protected:o int month;o int day;o int year;o void Init(int m,int d,int y)o month=m; day=d; year=y;o cout month / day / year endl;o o ; Page 2612.6 重载构造函数27n int main( )n Tdate

22、aday;n Tdate bday(10);n Tdate cday(2, 12);n Tdate dday(1, 2, 1998);n 运行结果:4/15/1995 4/10/1996 2/12/1997 1/2/1998Page 2712.6 重载构造函数28o多个构造函数可以通过给一个构造函数以参数默认值,使多个构造函数结合成一个。/ch12_8.cpp o# include o class Tdateo public:o Tdate(int m=4, int d=15, int y=1995)o month=m; day=d; year=y;o cout month / day/ ye

23、ar endl;o o /其他公共成员o protected:o int month;o int day;o int year;o ;Page 28l int main( )l Tdate aday;l Tdate bday(2);l Tdate cday(3, 12);l Tdate dday(1, 2, 1998);l 运行结果同上例12.6 重载构造函数29o重载构造函数若与参数默认值的构造函数发生冲突,则创建对象的语句会导致编译错误。o例:class Tdate public: Tdate(int d) month=4; day=d; year=1998; Tdate(int m, i

24、nt d=12) month=m; day=d; year=1997; /其他公共成员 protected: int month; int day; int year; ; int main( ) Tdate aday(11);/error:匹配哪个构造函数? 12.6 重载构造函数3012.7 默认构造函数oC+规定,每个类必须有一个构造函数,没有就不能创建任何对象。o若未提供一个类的构造函数,则C+提供一个默认的构造函数,它是个无参构造函数,仅负责创建对象,而不做任何初始化工作。o只要一个类定义了一个构造函数,C+就不再提供默认的默认构造函数。o与变量定义类似,在用默认构造函数创建对象时,

25、如果创建的是全局对象或静态对象,则对象的位模式全为0,否则, 对象值是随机的。31 例: class Student /无构造函数 protected: char name20; ; int main( ) Student noName; /ok:noName的内容 / 为随机值 public: Student( ) /一个空的无一个空的无 /参构造函数参构造函数等价于12.7 默认构造函数32o又例如,下面的代码定义了一个带参数的构造函数,面对创建无参对象,将不能正确的编译: o #include o class Studento public:o Student(char* pName)o

26、 strncpy(name,pName,sizeof(name);o namesizeof(name)-1=0;o o protected:o char name20;o ;o int main( )o o Student noName; /error:无匹配的构造函数 o 12.7 默认构造函数33o如果增加一个无参的构造函数,就可解决这个问题:o #include o class Studento public:o Student(char* pName)o strncpy(name,pName,sizeof(name);o namesizeof(name)-1=0;o o Student

27、( ) o protected:o char name20;o ;o int main( )o o Student noName; /oko Student ss(Jenny); /ok1. 12.7 默认构造函数34o说明的含糊性o先前的例子中创建Tdate类对象的方法是: Tdate aday; /为什么创建无参的对象无括号? Tdate bday(2); /对象的参数放在括号中 Tdate aday( ) ; /为什么不能这样声明?o根据C+的语法规定,这样是声明了一个名叫aday的普通函数,他返回Tdate类对象,并且没有参数。 又例如下面的代码,一个是创建对象,一个是声明函数: Td

28、ate oneday(10); /创建对象 Tdate oneday(int); /声明函数12.7 默认构造函数35o当一个类中的某个成员是另一个类的对象时,如何初始化这个成员?/ch12_10.cpp o # include o # include o int nextStudentID=0;o class StudentIDo public: o StudentID( )o value=+nextStudentID;o cout Assigning student id value endl;o o StudentID( )o -nextStudentID;o cout Destruct

29、ing id value endl;o o protected:o int value;o ; 36nclass Studentn public:n Student(char* pName=noName)n cout Constructing student pName n endl;o strcpy(name,pName);o namesizeof(name)-1=0; o o protected:o char name20;o StudentID id;o ; o int main( )o Student s(Randy);o Page 36运行结果:运行结果:Assigning stud

30、ent id 1Constructing student RandyDestructing id 137o如果想调用的函数不是默认构造函数又如何呢?o例如,下面的程序在创建学生对象时,赋予一个学号,希望将这个学号传给成员学号类对象id保存:/ch12_11.cpp o # include o # include o class StudentIDo public:o StudentID(int id=0)o value=id;o cout Assigning student id value endl;o o StudentID( )o cout Destructing id value en

31、dl;o o protected: o int value;o ;38oclass Studento public: o Student(char* pName=noName,int ssID=0) o cout Constructing studentpName endl;o strcpy(name,pName);o namesizeof(name)-1=0;o StudentID id(ssID);/实际上创建了一个局部对象ido o protected:o char name20;o StudentID id; o ; oint main( )o Student s(Randy,9818

32、);o 运行结果为:Assigning student id 0Constructing student RandyAssigning student id 9818Destructing id 9818Destructing id 0o此结果并未达到在初始化时赋予的学号传给学号类对象id的目的。39o那么,能否像下面这样在Student类中直接给id对象初始化呢?class Student public: Student(char *pname=“noName”, int ssID); protected: char name20; StudentID id(9818); /error /类

33、定义是不分配空间和初始化的;o 类是一个抽象概念,并不是一个实体,并不含有属性值,而只有对象才占有一定的空间, 含有明确的属性值。40o 类成员的构造应该在建立对象空间的结构时反映出来,即需要出现在函数调用刚刚转入之时,函数体执行(开括号)之前。o 类成员的初始化完全可以利用构造函数完成,在构造函数的原型中利用冒号语法,在冒号后面进行成员初始化: 构造函数(参数列表):成员初始化列表 例:例: /ch12_12.cpp41 /ch12_12.cppo # include o # include o oclass StudentIDo public:o StudentID(int id=0)o

34、value=id;o cout Assigning student id value endl;o o StudentID( )o cout Destructing id value endl;o o protected:o int value;o ;42oclass Studento public:o Student(char* pName=no name, int ssID=0) :id(ssID)o /冒号表示后面要对类的数据成员的构造函数进行调用。o /这里是调用以ssID为实参的StudentID构造函数。o cout Constructing student pName endl;

35、o strncpy(name,pName,sizeof(name);o namesizeof(name)-1=0;o o protected:o char name20;o StudentID id; o ;o int main( )o Student s(Randy,9818);o Student t(Jenny);o 运行结果:运行结果: Assigning student id 9818 Constructing student Randy Assigning student id 0 Constructing student Jenny Destructing id 0 Destruc

36、ting id 981843o 构造函数头后面如果是id( )的形式,表示调用StudentID的默认构造函数,并且可以省略。 Student(char* pName=no name, int ssID=0) :id( ) / 也可以写成: Student(char* pName=no name, int ssID=0) / 44o 构造类成员时调用类成员的哪个构造函数要是看参数匹配的情况。o 例如,在ch12_12.cpp中,如果StudentID构造函数中,参数没有默认值,即原型为: StudentID(int id);表明StudentID没有默认构造函数。o 而如果Student构造函

37、数的原型为: Student(char *pName=no name, int ssID) ;是无冒号形式,表明Student将调用StudentID的默认构造函数。于是,主函数中的两条创建Student对象的语句都要遇到不能匹配StudentID构造函数的错误。 45p冒号语法使得常量数据成员和引用数据成员的初始化成为可能。 例:class SillyClass public: SillyClass(int & i):ten(10),refI(i) protected: const int ten; /常量数据成员 int & refI; /引用数据成员 ; int main

38、( ) int i; SillyClass sc(i); 46o常量是不能被赋值的,引用变量也是不可重新指派的,一旦初始化,其值就永不改变。例:class SillyClass public: SillyClass(int &i) ten=10; /error:常量是不能被赋值 refI=i; /error:引用不可重新指派 protected: const int ten; int & refI; ; 47o数据成员若是一般变量,则放在冒号后面与放在函数体中初始化一样。 例:class SillyClass class SillyClass public: public: S

39、illyClass( ) SillyClass( ):d(10) /方法2 d=10;/方法1 protected: protected: int d; int d; ; ;48o说明一个变量并初始化有两种形式: int main( ) int m=10; /ok int n(20); /TC+3.0不允许,C+新标准允许 Student s=“Jenny”; /ok Student t(“Danny”); /ok:类的形式不受限制 o注意:赋值表达式中不允许:m(10); 只能:m=10; 构造函数的冒号后的初始化不允许用第一种形式: class SillyClass public: SillyClass2( ):d=10 /error protected: int d; ;491.局部和静态对象,以声明的顺序构造。o# include o# include oclass Studento public:o Student(char* pName=no name)o cout constructing student pName endl;o strncpy(name,pName,sizeof(name);o namesizeof(name)-1=0;o o Student( )o cout destructing

温馨提示

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

评论

0/150

提交评论