《C语言程序设计下.pptx》由会员分享,可在线阅读,更多相关《C语言程序设计下.pptx(240页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、第13章 运算符重载第1页/共240页讲授内容运算符重载的概念以成员函数的方式重载运算符以友元函数的方式重载运算符流插入和流提取运算符的重载一般单目和双目运算符的重载赋值运算符重载类型转换运算符重载第2页/共240页13.1 运算符重载的概念(1/2)类似于函数重载把传统的运算符用于用户自定义的对象直观自然,可以提高程序的可读性体现了C+的可扩充性通过定义名为operator的函数来实现运算符重载第3页/共240页例1:复数的、运算(1/5)/文件1:complex1.h复数类的定义#ifndefCOMPLEX1_H#defineCOMPLEX1_HclassComplexpublic:Com
2、plex(double=0.0,double=0.0);Complexoperator+(constComplex&)const;Complexoperator-(constComplex&)const;Complex&operator=(constComplex&);voidprint()const;private:doublereal;/realpartdoubleimaginary;/imaginarypart;#endif第4页/共240页例1:复数的、运算(2/5)/文件2:complex1.cpp复数类的成员函数定义#include#includecomplex1.hComplex
3、:Complex(doubler,doublei)real=r;imaginary=i;Complex Complex:operator+(const Complex&operand2)constComplexsum;sum.real=real+operand2.real;sum.imaginary=imaginary+operand2.imaginary;returnsum;第5页/共240页例1:复数的、运算(3/5)Complex Complex:operator-(const Complex&operand2)constComplexdiff;diff.real=real-operan
4、d2.real;diff.imaginary=imaginary-operand2.imaginary;returndiff;Complex&Complex:operator=(constComplex&right)real=right.real;imaginary=right.imaginary;return*this;/enablesconcatenationvoidComplex:print()constcout(real,imaginary);第6页/共240页例1:复数的、运算(4/5)/文件3:FIG13_1.cpp主函数定义#include#includecomplex1.hma
5、in()Complexx,y(4.3,8.2),z(3.3,1.1);coutx:;x.print();coutny:;y.print();coutnz:;z.print();x=y+z;coutnnx=y+z:n;第7页/共240页例1:复数的、运算(5/5)x.print();cout=;y.print();cout+;z.print();x=y-z;coutnnx=y-z:n;x.print();cout=;y.print();cout-;z.print();cout =的重载函数必须是类的成员函数第10页/共240页13.2 运算符成员函数与友元函数(1/2)以成员函数的方式重载运算符
6、单目运算符:不带参数,该类对象为唯一操作数双目运算符:带一个参数,该类对象为左操作数、参数为右操作数以友元函数的方式重载运算符单目运算符:带一个参数,该参数为唯一操作数,是自定义类的对象双目运算符:带两个参数,第一个参数为左操作数、第二个参数为右操作数,至少有一个参数为自定义类的对象第11页/共240页13.2 运算符成员函数与友元函数(2/2)如果双目运算符的左操作数不是自定义类的对象,重载函数不能定义为成员函数流插入运算符的重载运算符可交换性的实现(两个不同类型的操作数)运算符重载函数的定义要保证运算无二义性第12页/共240页13.3 单目运算符重载(1/3)操作数是自定义类的对象或对象
7、的引用作为成员函数重载没有参数作为友元函数重载参数为自定义类的对象或对象的引用 第13页/共240页例2:定义字符串类String,并以成员函数的方式重载运算符!以判断对象中的字符串是否为空串(1/3)/文件string.h#if!defined_STRING_H_#define_STRING_H_#includeclassStringpublic:String(char*m=);/使用默认参数的构造函数String();/定义运算符重载成员函数原型booloperator!();private:char*str;#endif第14页/共240页例2:定义字符串类String,并以成员函数的方
8、式重载运算符!以判断对象中的字符串是否为空串(2/3)/文件String.cpp#include#includestring.hString:String(char*m)str=newcharstrlen(m)+1;strcpy(str,m);String:String()deletestr;boolString:operator!()/实现运算符重载函数if(strlen(str)=0)returntrue;returnfalse;第15页/共240页例2:定义字符串类String,并以成员函数的方式重载运算符!以判断对象中的字符串是否为空串(3/3)/文件ex13_1.cpp#includ
9、e#includeString.hmain()Strings1,s2(somestring);if(!s1)/括号中等价于s1.operator!()couts1isNULL!endl;elsecouts1isnotNULL!endl;if(!s2)couts2isNULL!endl;elsecouts2isnotNULL!endl;return0;第16页/共240页程序执行结果:s1isNULL!s2isnotNULL!第17页/共240页例3:定义字符串类String,并以友元函数的方式重载运算符!以判断对象中的字符串是否为空串(1/3)/文件string.h#if!defined_ST
10、RING_H_#define_STRING_H_#includeclassString/定义运算符重载友元函数原型friendbooloperator!(String&s);public:String(char*m=);String();private:char*str;#endif第18页/共240页例3:定义字符串类String,并以友元函数的方式重载运算符!以判断对象中的字符串是否为空串(2/3)/文件String.cpp#include#includestring.hString:String(char*m)str=newcharstrlen(m)+1;strcpy(str,m);St
11、ring:String()deletestr;booloperator!(String&s)/实现运算符重载友元函数if(strlen(s.str)=0)returntrue;returnfalse;第19页/共240页例3:定义字符串类String,并以友元函数的方式重载运算符!以判断对象中的字符串是否为空串(3/3)/文件ex13_2.cpp#include#includeString.hmain()Strings1,s2(somestring);if(!s1)/括号中等价于operator!(s1)couts1isNULL!endl;elsecouts1isnotNULL!endl;if
12、(!s2)couts2isNULL!endl;elsecouts2isnotNULL!endl;return0;第20页/共240页程序执行结果:s1isNULL!s2isnotNULL!第21页/共240页13.3 单目运算符重载(2/3)特殊的单目运算符+、-以+为例(-同理),设b为类C的对象前自增,如:+b重载函数可为C的成员函数,原型为 C&operator+();也可为C的友元函数,原型为 C&operator+(C&);第22页/共240页13.3 单目运算符重载(3/3)后自增,如:b+重载函数可为C的成员函数,原型为 C&operator+(int);b+转换为函数调用b.o
13、perator+(0)重载函数也可为C的友元函数,原型为 C&operator+(C&,int);b+转换为函数调用operator+(b,0)第23页/共240页13.4 重载流插入和流提取运算符(1/2)cout+可以输出预定义类型的对象如:coutstring;cout是类ostream的一个对象(定义于头文件ostream.h中)如何实现用cout输出自定义类型的对象?Strings(string);coutsendl;第24页/共240页13.4 重载流插入和流提取运算符(2/2)应重载为成员函数还是友元函数?有选择吗?重载函数的返回类型应该是什么?有选择吗?重载函数的参数列表应该是
14、什么?有选择吗?第25页/共240页例4:定义字符串类String,并重载流插入运算符,实现用cout和cin直接输出和输入类String的对象(1/4)/文件string.h#if!defined_STRING_H_#define_STRING_H_#include#includeclassStringfriend ostream&operator(istream&input,String&s);public:String(char*m=);String();private:char*str;#endif第26页/共240页例4:定义字符串类String,并重载流插入运算符,实现用cout和
15、cin直接输出和输入类String的对象(2/4)/文件String.cpp#include#includestring.hString:String(char*m)str=newcharstrlen(m)+1;strcpy(str,m);String:String()deletestr;第27页/共240页例4:定义字符串类String,并重载流插入运算符,实现用cout和cin直接输出和输入类String的对象(3/4)/定义运算符重载函数ostream&operator(ostream&output,String&s)output重载函数istream&operator(istream&
16、input,String&s)chartemp1000;cintemp;deletes.str;s.str=newcharstrlen(temp)+1;strcpy(s.str,temp);returninput;第28页/共240页例4:定义字符串类String,并重载流插入运算符,实现用cout和cin直接输出和输入类String的对象(4/4)/文件ex13_3.cpp#include#includeString.hmain()Strings1,s2;cout Please input two strings:s1s2;coutOutputis:endl;couts1-s1endls2-
17、s2endl;return0;第29页/共240页程序执行结果:Pleaseinputtwostrings:WuhanChangshaOutputis:s1-Wuhans2-Changsha第30页/共240页13.5 双目运算符重载(1/2)双目运算符的重载形式,考虑运算符对左操作数是否有要求是否要保留运算符的可交换性(只针对具有可交换性的运算符而言)双目运算符重载为非静态成员函数带有一个参数左操作数必须为该类的对象或对象的引用双目运算符重载为带有两个参数的非成员函数参数之一必须是类的对象或对象的引用第31页/共240页例5:定义类String,重载运算符+=,x+=y将y中的字符串连接到x
18、的后面(1/5)/文件string.h#if!defined_STRING_H_#define_STRING_H_#includeclassStringfriend ostream&operator(istream&input,String&s);public:String(char*m=);String();String&operator+=(String&s);private:char*str;#endif第32页/共240页例5:定义类String,重载运算符+=,x+=y将y中的字符串连接到x的后面(2/5)/文件String.cpp,类String的实现#include#includ
19、estring.hString:String(char*m)str=newcharstrlen(m)+1;strcpy(str,m);String:String()deletestr;/定义运算符重载函数ostream&operator(ostream&output,String&s)output重载函数istream&operator(istream&input,String&s)chartemp1000;cintemp;deletes.str;s.str=newcharstrlen(temp)+1;strcpy(s.str,temp);returninput;第34页/共240页例5:定义
20、类String,重载运算符+=,x+=y将y中的字符串连接到x的后面(4/5)/定义运算符+=重载函数String&String:operator+=(String&s)chartemp4096;strcpy(temp,str);strcat(temp,s.str);deletestr;str=newcharstrlen(temp)+1;strcpy(str,temp);return*this;第35页/共240页例5:定义类String,重载运算符+=,x+=y将y中的字符串连接到x的后面(5/5)/文件ex13_4.cpp,测试重载的运算符#include#includeString.hm
21、ain()Strings1,s2;cins1s2;couts1-s1endl;s1+=s2;couts1afters1+=s2-s1endl;return0;第36页/共240页程序执行结果:WuhanChangshas1-Wuhans1afters1+=s2-WuhanChangsha第37页/共240页13.5 双目运算符重载(2/2)如果要使用友元的方式重载前面例子中的+=,要如何考虑?函数名?参数列表?返回类型?返回值?第38页/共240页用友元函数重载运算符+classString/声明友元函数operator+=friend String&operator+=(String&x,S
22、tring&y);.;/运算符重载函数operator+=的实现String&operator+=(String&x,String&y)chartemp4096;strcpy(temp,x.str);strcat(temp,y.str);deletex.str;x.str=newcharstrlen(temp)+1;strcpy(x.str,temp);returnx;第39页/共240页13.6 赋值运算符重载(1/2)赋值运算符可直接用在自定义类的对象赋值默认操作是逐个拷贝对象的所有数据成员如果对象中包含动态分配的空间,这种赋值方式就不合适了,如 String s1(abc),s2(def
23、);s1=s2;赋值的结果是:对象s1和s2的指针str都指向了同一块数据空间第40页/共240页13.6 赋值运算符重载(2/2)问题:存放“abc”的空间被遗弃,将无法被访问如果对象s1被撤销其析构函数将释放其指针str所指向的空间“def”对象s2的指针str所指向的空间被破坏访问s2的数据、撤销s2时都会发生指针错误对象中包含动态分配的空间,赋值运算符需要自己重载第41页/共240页例6:定义类String,重载运算符+和=(1/6)/文件string.h,定义类String#if!defined_STRING_H_#define_STRING_H_#includeclassStrin
24、gfriend ostream&operator(istream&input,String&s);public:String(char*m=);String();String&operator=(String&s);String&operator+(String&s);private:char*str;#endif第42页/共240页例6:定义类String,重载运算符+和=(2/6)/文件String.cpp,类String的实现#include#includestring.hString:String(char*m)str=newcharstrlen(m)+1;strcpy(str,m);
25、String:String()deletestr;/定义运算符重载函数ostream&operator(ostream&output,String&s)output重载函数istream&operator(istream&input,String&s)chartemp1000;cintemp;deletes.str;s.str=newcharstrlen(temp)+1;strcpy(s.str,temp);returninput;第44页/共240页例6:定义类String,重载运算符+和=(4/6)String&String:operator=(String&s)if(&s=this)/检
26、查是否自我赋值,非常重要return*this;deletestr;/释放当前对象的数据空间str=newcharstrlen(s.str)+1;/重新分配适当大小的空间strcpy(str,s.str);return*this;第45页/共240页例6:定义类String,重载运算符+和=(5/6)String&String:operator+(String&s)staticStringres;/为什么要声明res为静态对象chartemp4096;strcpy(temp,str);strcat(temp,s.str);deleteres.str;res.str=newcharstrlen(
27、temp)+1;strcpy(res.str,temp);returnres;第46页/共240页例6:定义类String,重载运算符+和=(6/6)/文件ex13_5.cpp,测试重载的运算符#include#includeString.hmain()Strings1,s2;cout Please input two strings:s1s2;coutOutputis:endl;couts1-s1endl;couts2-s2endl;s1=s1+s2;coutafters1=s1+s2;endl;couts1-s1endl;return0;第47页/共240页程序执行结果:Pleaseinp
28、uttwostrings:WuhanChangshaOutputis:s1-Wuhans2-Changshaafters1=s1+s2;s1-WuhanChangsha第48页/共240页13.7 类型之间的转换(1/4)自定义类的对象和其它类型之间也可以实现隐式或显式的转换类似提升和类型强制转换两种类型转换方式其它类型的数据到自定义类的对象的转换通过转换构造函数自定义类的对象到其它类型的数据的转换通过类型转换运算符函数第49页/共240页13.7 类型之间的转换(2/4)类型转换运算符函数必须是类的非静态成员函数,不能是友元函数没有参数(操作数是什么?)不能指定返回类型(其实已经指定了)第5
29、0页/共240页13.7 类型之间的转换(3/4)类型转换运算符函数名:operator+类型名例子:operator int()const;将类的对象转换成一个int类型的数据如果obj是该自定义类的一个对象,则:(int)obj;等价于:obj.operator int();该函数根据对象obj生成一个int类型的数据需要的时候,编译器会自动调用类型转换运算符函数来建立一个临时对象就像对内部类型使用提升规则一样 第51页/共240页13.7 类型之间的转换(4/4)转换构造函数只有一个参数,就是其它类型的对象根据该对象初始化自定义类型的对象转换构造函数例子String(constchar*
30、m=);String(constintlen);第52页/共240页学习目的检测了解运算符重载的概念和意义掌握运算符重载的限制掌握流插入和流提取运算符的重载方法掌握以成员函数的方式重载运算符的方法掌握以友元函数的方式重载运算符的方法了解运算符成员函数和友元函数的区别掌握赋值运算符重载的方法了解类型转换运算符的重载方法第53页/共240页作业13.3 13.6 13.8第54页/共240页第14章 继承第55页/共240页讲授内容继承和派生的基本概念 继承的定义 在派生类中重定义基类的函数 基类和派生类对象的转换 类指针的使用 继承关系中构造函数、析构函数之间的关系 多重继承 复合与继承的关系第
31、56页/共240页14.1 继承和派生的概念(1/2)实体之间的关系有(has_a)类的复合班级和学校,班级不是学校,学校拥有班级,班级是学校的一部分是(is_a)类的继承中学和学校,中学是学校,学校不能拥有中学,中学是学校的一个特例,是某一种学校第57页/共240页14.1 继承和派生的概念(2/2)继承继承允许以现有的类为基础来构建新类新类(派生类)继承现有类(基类)的属性和行为派生类可以修改继承的属性和行为派生类可以增加新的属性和行为派生类对象也是基类对象派生类对象和基类对象可以被统一管理复合和继承可以直观自然地描述客观世界中的实体第58页/共240页14.2 继承的定义(1/9)继承结
32、构的例子无处不在家具和柜子建筑和房子道路和高速公路动物和猫电视和彩色电视电脑和笔记本电脑第59页/共240页例子1:定义基类Mammal和派生类LionclassMammalpublic:Mammal();Mammal();.;classLion:publicMammalpublic:Lion();Lion();.;第60页/共240页14.2 继承的定义(2/9)继承的三种方式公有继承(public)受保护继承(protected)私有继承(private)基类中的成员被派生类继承后成员对外的可见性会有所不同 第61页/共240页14.2 继承的定义(3/9)公有继承(public)基类中公
33、有成员和受保护成员被继承后可见性不变受保护继承(protected)基类中公有成员和受保护成员被继承后都是受保护的私有继承(private)基类中公有成员和受保护成员被继承后都是私有的第62页/共240页14.2 继承的定义(4/9)基类中的私有成员能被派生类继承不能被派生类的成员函数直接访问可通过定义于基类的公有和受保护成员函数访问第63页/共240页例子2:私有继承的例子classMammalpublic:Mammal();Mammal();.;classLion:privateMammalpublic:Lion();Lion();.;第64页/共240页14.2 继承的定义(5/9)类的
34、层次一个类可以是某个继承关系中的基类,也可以是另一个继承关系中的派生类类A派生出类B,类B又派生出类C,则类B是类C的直接基类,类A是类C的间接基类 定义派生类时,直接基类要明确列出,间接基类不用列出 第65页/共240页例子3:间接基类的例子classAprotected:intaMember;.;classB:protectedAprotected:intbMember;.;classC:privateBprotected:intcMember;.;第66页/共240页14.2 继承的定义(6/9)在派生类中重定义基类的函数派生类自动继承基类的所有成员如果基类成员函数功能不满足需要在派生类
35、中重定义该函数派生类对象可以直接访问自己定义的函数,也可以访问定义于基类被覆盖的函数调用方式:基类名+:+函数名第67页/共240页例子4:派生类重定义基类成员函数(1/5)/文件people.h#if!defined_PEOPLE_H_#define_PEOPLE_H_classPeoplepublic:/构造函数中参数s大于0表示男性,否则为女性People(char*str,ints);People();voidshow();private:char*name;intsex;#endif第68页/共240页例子4:派生类重定义基类成员函数(2/5)/文件people.cpp#includ
36、e#include#includepeople.hPeople:People(char*str,ints)name=newcharstrlen(str)+1;strcpy(name,str);if(s0)sex=1;/男性elsesex=0;/女性People:People()deletename;voidPeople:show()coutMynameisname,Iam;cout (sex?male.:female.)endl;第69页/共240页例子4:派生类重定义基类成员函数(3/5)/文件teacher.h#includepeople.h#if!defined_TEACHER_H_#d
37、efine_TEACHER_H_classTeacher:publicPeoplepublic:Teacher(char*str,int s,char*sch,inty);Teacher();voidshow();private:char*school;intyears;#endif第70页/共240页例子4:派生类重定义基类成员函数(4/5)/文件teacher.cpp#include#include#includeteacher.hTeacher:Teacher(char*str,int s,char*sch,int y):People(str,s)/调用基类的构造函数school=new
38、charstrlen(sch)+1;strcpy(school,sch);years=(y0)?y:0;Teacher:Teacher()deleteschool;voidTeacher:show()People:show();/调用基类被重定义的函数coutIaminschoolforyearsyears.endl;第71页/共240页例子4:派生类重定义基类成员函数(5/5)/文件ex14_1.cpp/测试类Teacher#include#includeteacher.hmain()Peoplepeople(Zhangsan,1);Teacherteacher(Lisi,-1,WuhanU
39、niversity,4);people.show();coutendl;teacher.show();return0;第72页/共240页14.2 继承的定义(7/9)创建派生类对象时,派生类构造函数要调用基类的构造函数先执行基类构造函数,然后执行派生类构造函数体基类构造函数需要参数时,显式调用,格式:Teacher:Teacher(char*s,int t,char*c,int y):People(s,c)/调用基类的构造函数.基类构造函数不需要参数时(有默认构造函数),隐式调用基类的构造函数不被继承,但会被自动调用第73页/共240页14.2 继承的定义(8/9)派生类重定义基类的函数重定
40、义函数的函数原型和基类中被重定义函数的函数原型必须完全相同 不同则是函数重载重定义之后两个函数共存,但调用方法不同调用基类函数:基类名+:+函数名调用派生类函数:直接调用第74页/共240页14.2 继承的定义(9/9)派生类和基类的转换派生类和基类具有不同的类型派生类对象也是基类对象,可以作为基类对象处理可以把派生类对象直接赋值给基类对象基类对象不能直接作为派生类对象处理(需要类型转换)第75页/共240页14.3 类指针(1/3)类是一种新的用户自定义类型类名可以用来声明变量(类的对象)、数组、指针等类的指针可以操作类的对象,也可以操作派生类的对象(派生类对象也是基类对象)派生类对象和基类
41、对象可以通过指针统一操作和管理第76页/共240页14.3 类指针(2/3)类指针操作类对象的几种可能基类指针操作基类对象(自然)派生类指针操作派生类对象(自然)基类指针操作派生类对象把派生类对象作为基类对象看(安全)派生类指针操作基类对象把基类对象作为派生类对象看(危险)第77页/共240页例子5:用类指针操作基类和派生类对象(1/9)/文件people.h#if!defined_PEOPLE_H_#define_PEOPLE_H_classPeoplepublic:/构造函数中参数s大于0表示男性,否则为女性People(char*str,ints);People();intgetSex(
42、);char*getName();private:char*name;intsex;#endif第78页/共240页例子5:用类指针操作基类和派生类对象(2/9)/文件people.cpp#include#include#includepeople.hPeople:People(char*str,ints)name=newcharstrlen(str)+1;strcpy(name,str);if(s0)sex=1;/男性elsesex=0;/女性People:People()deletename;第79页/共240页例子5:用类指针操作基类和派生类对象(3/9)intPeople:getSex
43、()returnsex;char*People:getName()staticcharstr128;strcpy(str,name);returnstr;第80页/共240页例子5:用类指针操作基类和派生类对象(4/9)/文件teacher.h#includepeople.h#if!defined_TEACHER_H_#define_TEACHER_H_classTeacher:publicPeoplepublic:Teacher(char*str,int s,char*sch,inty);Teacher();intgetWorkYears();char*getSchool();private
44、:char*school;intyears;#endif第81页/共240页例子5:用类指针操作基类和派生类对象(5/9)/文件teacher.cpp#include#include#includeteacher.hTeacher:Teacher(char*str,ints,char*sch,inty):People(str,s)/调用基类的构造函数school=newcharstrlen(sch)+1;strcpy(school,sch);years=(y0)?y:0;Teacher:Teacher()deleteschool;第82页/共240页例子5:用类指针操作基类和派生类对象(6/9
45、)intTeacher:getWorkYears()returnyears;char*Teacher:getSchool()staticcharstr1024;strcpy(str,school);returnstr;第83页/共240页例子5:用类指针操作基类和派生类对象(7/9)/文件ex14_2.cpp#include#includeteacher.hmain()Peoplep(ZhangSan,1),*pptr;Teacher t(Li Si,0,Wuhan University,4),*tptr;/用基类指针操作对象pptr=&p;/用基类指针指向基类对象coutPeoplep:ge
46、tName(),getSex()?male:female)endlendl;pptr=&t;/用基类指针指向派生类对象coutTeacher t:getName(),getSex()?male:female)endl;第84页/共240页例子5:用类指针操作基类和派生类对象(8/9)/要调用定义于派生类中的函数必须进行类型的强制转换couttingetSchool()forgetWorkYears()years.endlendl;/用派生类指针操作对象tptr=(Teacher*)&p;/用派生类指针指向基类对象coutPeople p:getName(),getSex()?male:fema
47、le)endl;/危险,访问了不存在的属性couttin getSchool()forgetWorkYears()years.endl;第85页/共240页例子5:用类指针操作基类和派生类对象(9/9)tptr=&t;/用派生类指针指向派生类对象/调用基类中定义的函数coutPeople p:getName(),getSex()?male:female)endl;cout tin getSchool()forgetWorkYears()years.endl;return0;第86页/共240页程序运行结果:Peoplep:ZhangSan,maleTeachert:LiSi,femaleinW
48、uhanUniversityfor4years.Peoplep:ZhangSan,malein?for4278034years.Peoplep:LiSi,femaleinWuhanUniversityfor4years.第87页/共240页14.3 类指针(3/3)常用的程序设计方法用数组或链表组织和管理继承关系中的各对象然后用基类指针操作它们麻烦可能需要类型转换下一章的多态性可以解决这个问题第88页/共240页14.4 继承中的构造函数和析构函数(1/2)派生类不继承基类的构造函数和析构函数派生类和基类的构造函数和析构函数之间是一种自动调用的关系派生类的构造函数需要调用基类的构造函数对其中定
49、义于基类的数据成员进行初始化显式调用(需要传递参数)隐式调用(不需要传递参数)派生类的析构函数也需要调用基类的析构函数做一些和基类相关的清理工作第89页/共240页14.4 继承中的构造函数和析构函数(2/2)构造函数的执行顺序先调用基类的构造函数初始化从基类继承的数据成员再执行自己的函数体初始化定义于派生类的数据成员析构函数的执行顺序派生类的析构函数先执行自己的函数体再调用基类的析构函数第90页/共240页例子6:继承关系中构造函数和析构函数的执行顺序(1/5)/文件people.h/定义类People#if!defined_PEOPLE_H_#define_PEOPLE_H_classPe
50、oplepublic:People(char*str);/构造函数People();/析构函数protected:char*name;#endif第91页/共240页例子6:继承关系中构造函数和析构函数的执行顺序(2/5)/文件people.cpp,类People的实现#include#include#includepeople.h/构造函数的实现People:People(char*str)name=newcharstrlen(str)+1;strcpy(name,str);coutPeopleconstruct:nameendl;/析构函数的实现People:People()coutPeo