C语言程序设计PPT第七章继承与派生

PPT
  • 阅读 69 次
  • 下载 0 次
  • 页数 66 页
  • 大小 198.012 KB
  • 2022-11-12 上传
  • 收藏
  • 违规举报
  • © 版权认领
下载文档30.00 元 加入VIP免费下载
此文档由【小橙橙】提供上传,收益归文档提供者,本网站只提供存储服务。若此文档侵犯了您的版权,欢迎进行违规举报版权认领
C语言程序设计PPT第七章继承与派生
可在后台配置第一页与第二页中间广告代码
C语言程序设计PPT第七章继承与派生
可在后台配置第二页与第三页中间广告代码
C语言程序设计PPT第七章继承与派生
可在后台配置第三页与第四页中间广告代码
C语言程序设计PPT第七章继承与派生
C语言程序设计PPT第七章继承与派生
还剩10页未读,继续阅读
【这是免费文档,您可以免费阅读】
/ 66
  • 收藏
  • 违规举报
  • © 版权认领
下载文档30.00 元 加入VIP免费下载
文本内容

【文档说明】C语言程序设计PPT第七章继承与派生.ppt,共(66)页,198.012 KB,由小橙橙上传

转载请保留链接:https://www.ichengzhen.cn/view-2208.html

以下为本文档部分文字说明:

1第七章继承与派生C++语言程序设计C++语言程序设计2本章主要内容⚫类的继承⚫类成员的访问控制⚫单继承与多继承⚫派生类的构造、析构函数⚫类成员的标识与访问C++语言程序设计3类的继承与派生⚫保持已有类的特性而构

造新类的过程称为继承。⚫在已有类的基础上新增自己的特性而产生新类的过程称为派生。⚫被继承的已有类称为基类(或父类)。⚫派生出的新类称为派生类。C++语言程序设计4继承与派生问题举例工具车轿车面包车小汽车卡车旅行车汽车交通工具类的继承与派生C++语言程序设计5继承与派

生问题举例猴子狮子虎猎豹猫鸟动物类的继承与派生猫科C++语言程序设计6继承与派生问题举例圆矩形几何形状类的继承与派生C++语言程序设计7继承与派生问题举例兼职技术人员销售经理管理人员销售人员雇员类的继承与派生C++语言程序设计

8继承与派生的目的⚫继承的目的:实现代码重用。⚫派生的目的:当新的问题出现,原有程序无法解决(或不能完全解决)时,需要对原有程序进行改造。类的继承与派生C++语言程序设计9派生类的声明class派生类名:继承方式基类名{成员声明;}

类的继承与派生C++语言程序设计10继承方式⚫不同继承方式的影响主要体现在:–派生类成员对基类成员的访问权限–通过派生类对象对基类成员的访问权限⚫三种继承方式–公有继承–私有继承–保护继承类成员的访问控制C++语言程序设计11公有继承(public)⚫基类的public和protected成

员的访问属性在派生类中保持不变,但基类的private成员不可直接访问。⚫派生类中的成员函数可以直接访问基类中的public和protected成员,但不能直接访问基类的private成员。⚫通过派生类的对象只能访问基类的public成员。类成员的访问控制C++

语言程序设计12例7-1公有继承举例classPoint//基类Point类的声明{public://公有函数成员voidInitP(floatxx=0,floatyy=0){X=xx;Y=yy;}voidMove(floatxOff,f

loatyOff){X+=xOff;Y+=yOff;}floatGetX(){returnX;}floatGetY(){returnY;}private://私有数据成员floatX,Y;};类成员的访问控制classRectan

gle:publicPoint//派生类声明{public://新增公有函数成员voidInitR(floatx,floaty,floatw,floath){InitP(x,y);W=w;H=h;}//调用基类公有成员函数floatGetH(){returnH;}floatGetW(){retur

nW;}private://新增私有数据成员floatW,H;};13#include<iostream.h>#include<cmath.h>intmain(){Rectanglerect;rect.InitR(2

,3,20,10);//通过派生类对象访问基类公有成员rect.Move(3,2);cout<<rect.GetX()<<','<<rect.GetY()<<','<<rect.GetH()<<','<<rect.GetW()<<en

dl;return0;}14C++语言程序设计15私有继承(private)⚫基类的public和protected成员都以private身份出现在派生类中,但基类的private成员不可直接访问。⚫派生类中的

成员函数可以直接访问基类中的public和protected成员,但不能直接访问基类的private成员。⚫通过派生类的对象不能直接访问基类中的任何成员。类成员的访问控制C++语言程序设计16例7-2私有继承举例classRectangle:privatePoin

t//派生类声明{public://新增外部接口voidInitR(floatx,floaty,floatw,floath){InitP(x,y);W=w;H=h;}//访问基类公有成员voidMove(floatxOff,f

loatyOff){Point::Move(xOff,yOff);}floatGetX(){returnPoint::GetX();}floatGetY(){returnPoint::GetY();}floatGetH(){returnH;}flo

atGetW(){returnW;}private://新增私有数据floatW,H;};类成员的访问控制#include<iostream.h>#include<cmath.h>intmain(){//通过派生类对象只能访问本类成员Rectanglerect;r

ect.InitR(2,3,20,10);rect.Move(3,2);cout<<rect.GetX()<<','<<rect.GetY()<<','<<rect.GetH()<<','<<rect.GetW()<<endl;return0;}17C++语言程序设计18保护继承(p

rotected)⚫基类的public和protected成员都以protected身份出现在派生类中,但基类的private成员不可直接访问。⚫派生类中的成员函数可以直接访问基类中的public和protected成员,但不能直接访问基类的private成员。⚫通

过派生类的对象不能直接访问基类中的任何成员类成员的访问控制C++语言程序设计19protected成员的特点与作用⚫对建立其所在类对象的模块来说,它与private成员的性质相同。⚫对于其派生类来说,它与public成员的性质相同。⚫既实现了数据隐藏,又方

便继承,实现代码重用。类成员的访问控制C++语言程序设计20例7-3protected成员举例classA{protected:intx;}intmain(){Aa;a.x=5;//错误}类成员的访问控制classA{protected:intx;}classB:publicA{pub

lic:voidFunction();};voidB:Function(){x=5;//正确}21C++语言程序设计22类型兼容规则⚫一个公有派生类的对象在使用上可以被当作基类的对象,反之则禁止。具体表现在:–派生类的

对象可以被赋值给基类对象。–派生类的对象可以初始化基类的引用。–指向基类的指针也可以指向派生类。⚫通过基类对象名、指针只能使用从基类继承的成员类型兼容C++语言程序设计23例7-4类型兼容规则举例#include<iostream.h>classB0//基类B0声明{public:void

display(){cout<<"B0::display()"<<endl;}//公有成员函数};类型兼容classB1:publicB0{public:voiddisplay(){cout<<"B1

::display()"<<endl;}};classD1:publicB1{public:voiddisplay(){cout<<"D1::display()"<<endl;}};voidfun(B0*ptr){ptr->display();//"对象指针->成员名"}24intmain

()//主函数{B0b0;//声明B0类对象B1b1;//声明B1类对象D1d1;//声明D1类对象B0*p;//声明B0类指针p=&b0;//B0类指针指向B0类对象fun(p);p=&b1;//B0类指针指向B1

类对象fun(p);p=&d1;//B0类指针指向D1类对象fun(p);}运行结果:B0::display()B0::display()B0::display()25C++语言程序设计26基类与派生类的对应关系⚫单继承–派生类只从一个基类派生。⚫多继承–派生类从多个基类派生。⚫多重

派生–由一个基类派生出多个不同的派生类。⚫多层派生–派生类又作为基类,继续派生新的类。单继承与多继承C++语言程序设计27多继承时派生类的声明class派生类名:继承方式1基类名1,继承方式2基类名2,...{成员声明;}注意:每一个“继承方式”,只用于限制对紧

随其后之基类的继承。单继承与多继承C++语言程序设计28多继承举例classA{public:voidsetA(int);voidshowA();private:inta;};classB{public:voidsetB(int);voidshowB();private:intb;}

;classC:publicA,privateB{public:voidsetC(int,int,int);voidshowC();private:intc;};单继承与多继承voidA::setA(intx){a=x;}voidB::setB(intx){b=x;}voidC::setC(i

ntx,inty,intz){//派生类成员直接访问基类的//公有成员setA(x);setB(y);c=z;}//其他函数实现略intmain(){Cobj;obj.setA(5);obj.showA();obj.se

tC(6,7,9);obj.showC();//obj.setB(6);错误//obj.showB();错误return0;}29C++语言程序设计30继承时的构造函数⚫基类的构造函数不被继承,派生类中需要声明自己的构造函数。⚫声明构造函数时,只需要对

本类中新增成员进行初始化,对继承来的基类成员的初始化,自动调用基类构造函数完成。⚫派生类的构造函数需要给基类的构造函数传递参数派生类的构造、析构函数C++语言程序设计31单一继承时的构造函数派生类名::派生类名(基类所需的形参,本类成员所需的形参):基类名(参数表){本类成员初始化赋值语句

;};派生类的构造、析构函数C++语言程序设计32单一继承时的构造函数举例#include<iostream.h>classB{public:B();B(inti);~B();voidPrint()const;private:i

ntb;};派生类的构造、析构函数B::B(){b=0;cout<<"B'sdefaultconstructorcalled."<<endl;}B::B(inti){b=i;cout<<"B'sconstructorcal

led."<<endl;}B::~B(){cout<<"B'sdestructorcalled."<<endl;}voidB::Print()const{cout<<b<<endl;}33classC:publicB{public:C();C(inti,intj);~C()

;voidPrint()const;private:intc;};34C::C(){c=0;cout<<"C'sdefaultconstructorcalled."<<endl;}C::C(inti,intj):B(i){c=j;cout<<"C

'sconstructorcalled."<<endl;}C::~C(){cout<<"C'sdestructorcalled."<<endl;}voidC::Print()const{B::Print();cout<<c<<endl;}intmain(){Cobj(5,6

);obj.Print();}35C++语言程序设计36多继承时的构造函数派生类名::派生类名(基类1形参,基类2形参,...基类n形参,本类形参):基类名1(参数),基类名2(参数),...基类名n(参数){本类成员初始化赋值语句;};派生类的构造、析构函数C++语言程序设

计37派生类与基类的构造函数⚫当基类中声明有默认形式的构造函数或未声明构造函数时,派生类构造函数可以不向基类构造函数传递参数。⚫若基类中未声明构造函数,派生类中也可以不声明,全采用默认形式构造函数。⚫当基类声明有带形参的构造函数时,派生类也应

声明带形参的构造函数,并将参数传递给基类构造函数。派生类的构造、析构函数C++语言程序设计38多继承且有内嵌对象时的构造函数派生类名::派生类名(基类1形参,基类2形参,...基类n形参,本类形参):基类名1(参数),基类名2(参数),...基类名n(参数),对象数据成员的初始化{本类成员初

始化赋值语句;};派生类的构造、析构函数C++语言程序设计39构造函数的调用顺序1.调用基类构造函数,调用顺序按照它们被继承时声明的顺序(从左向右)。2.调用成员对象的构造函数,调用顺序按照它们在类中声明的顺序。3.派生类的构造函数体中的内容。派生类的构造、析构函数C++语言程序设计40拷

贝构造函数⚫若建立派生类对象时调用默认拷贝构造函数,则编译器将自动调用基类的默认拷贝构造函数。⚫若编写派生类的拷贝构造函数,则需要为基类相应的拷贝构造函数传递参数。例如:C::C(C&c1):B(c1){…}派生类的构造、析构函数C++语言程序设计41例7-5派生类构造函数举例#include<

iostream.h>classB1//基类B1,构造函数有参数{public:B1(inti){cout<<"constructingB1"<<i<<endl;}};classB2//基类B2,构造函数有参数{public:B2(intj){c

out<<"constructingB2"<<j<<endl;}};classB3//基类B3,构造函数无参数{public:B3(){cout<<"constructingB3*"<<endl;}};派生类的构

造、析构函数classC:publicB2,publicB1,publicB3{public://派生类的公有成员C(inta,intb,intc,intd):B1(a),memberB2(d),memberB1(c),

B2(b){}private://派生类的私有对象成员B1memberB1;B2memberB2;B3memberB3;};intmain(){Cobj(1,2,3,4);}运行结果:constructingB22constru

ctingB11constructingB3*constructingB13constructingB24constructingB3*42C++语言程序设计43继承时的析构函数⚫析构函数也不被继承,派生类自行声明

⚫声明方法与一般(无继承关系时)类的析构函数相同。⚫不需要显式地调用基类的析构函数,系统会自动隐式调用。⚫析构函数的调用次序与构造函数相反。派生类的构造、析构函数C++语言程序设计44例7-6派生类析构函数举例派生类的构造、析构函数#include<iostream.h>classB1/

/基类B1声明{public:B1(inti){cout<<"constructingB1"<<i<<endl;}~B1(){cout<<"destructingB1"<<endl;}};classB2//基类B2声明{public:B2(intj){cout<<"constructingB2"<

<j<<endl;}~B2(){cout<<"destructingB2"<<endl;}};classB3//基类B3声明{public:B3(){cout<<"constructingB3*"<<endl;}~B3(){cout<<"destructin

gB3"<<endl;}};classC:publicB2,publicB1,publicB3{public:C(inta,intb,intc,intd):B1(a),memberB2(d),member

B1(c),B2(b){}private:B1memberB1;B2memberB2;B3memberB3;};intmain(){Cobj(1,2,3,4);}45C++语言程序设计46例7-6运行结果constructingB

22constructingB11constructingB3*constructingB13constructingB24constructingB3*destructingB3destructingB2destructingB1destructingB3destructingB1destruc

tingB2C++语言程序设计47同名隐藏规则当派生类与基类中有相同成员时:⚫若未强行指名,则通过派生类对象使用的是派生类中的同名成员。⚫如要通过派生类对象访问基类中被覆盖的同名成员,应使用基类名限定。派生类成员的标识与访问C

++语言程序设计48例7-7多继承同名隐藏举例派生类成员的标识与访问#include<iostream.h>classB1//声明基类B1{public://外部接口intnV;voidfun(){cou

t<<"MemberofB1"<<endl;}};classB2//声明基类B2{public://外部接口intnV;voidfun(){cout<<"MemberofB2"<<endl;}};classD1:publicB1,publicB2{public

:intnV;//同名数据成员voidfun(){cout<<"MemberofD1"<<endl;}//同名函数成员};intmain(){D1d1;d1.nV=1;//对象名.成员名标识,访问D1类成员d1.fun();

d1.B1::nV=2;//作用域分辨符标识,访问基类B1成员d1.B1::fun();d1.B2::nV=3;//作用域分辨符标识,访问基类B2成员d1.B2::fun();}49C++语言程序设计50二义性问题⚫在多继承时,基类与派生类之间,或基类之间出现同名成员时,将出现访问时的二义

性(不确定性)——采用虚函数(参见第8章)或同名隐藏规则来解决。⚫当派生类从多个基类派生,而这些基类又从同一个基类派生,则在访问此共同基类中的成员时,将产生二义性——采用虚基类来解决。派生类成员的标识与访问C++语言程序设计51二义性问题举例(一)classA{publi

c:voidf();};classB{public:voidf();voidg()};classC:publicA,piblicB{public:voidg();voidh();};如果声明:Cc1;则c1.f();具有二义性而c1.g(

);无二义性(同名覆盖)派生类成员的标识与访问C++语言程序设计52二义性的解决方法⚫解决方法一:用类名来限定c1.A::f()或c1.B::f()⚫解决方法二:同名覆盖在C中声明一个同名成员函数f(),f()再根据需要调用A::f()或B::f()派生类成员的标

识与访问C++语言程序设计53二义性问题举例(二)classB{public:intb;}classB1:publicB{private:intb1;}classB2:publicB{private:intb2;};classC:publicB1,publicB2{public:

intf();private:intd;}派生类成员的标识与访问派生类C的对象的存储结构示意图:bb1bb2dB类成员B类成员B1类成员B2类成员C类对象有二义性:Cc;c.bc.B::b无二义性:c.B1::bc.B2::b54C++语言程序设计55虚基类⚫虚基类的引入–用于有共同基类的场合

⚫声明–以virtual修饰说明基类例:classB1:virtualpublicB⚫作用–主要用来解决多继承时可能发生的对同一基类继承多次而产生的二义性问题.–为最远的派生类提供一的基类成员,而不重复产生多次拷贝⚫注意:–在第一级继承时就要将

共同基类设计为虚基类。C++语言程序设计56虚基类举例classB{private:intb;};classB1:virtualpublicB{private:intb1;};classB2:virtualpublicB{private:intb2;};classC:publ

icB1,publicB2{private:floatd;}下面的访问是正确的:Ccobj;cobj.b;虚基类虚基类的派生类对象存储结构示意图:BB1B2Cb1b2dB1类成员B2类成员C类对象bB类成员57C++语言程序设计58例7-8虚基类举例虚基类D1nV:

intnVd:intB1::nV1:intB2::nV2:intfund():voidfun():voidB1nV1:intB2nV2:intD1nVd:intfund():void<<virtual>>B0nV:intfun()B0B1新增成员B

0B2新增成员D1新增成员B0B0B1B2D1nV,fun()59#include<iostream.h>classB0//声明基类B0{public://外部接口intnV;voidfun(){cout<<"MemberofB0"<<endl;}};cl

assB1:virtualpublicB0//B0为虚基类,派生B1类{public://新增外部接口intnV1;};classB2:virtualpublicB0//B0为虚基类,派生B2类{public://新增外部接口intnV2;};60classD1

:publicB1,publicB2//派生类D1声明{public://新增外部接口intnVd;voidfund(){cout<<"MemberofD1"<<endl;}};intmain()//程序主函数{D1d1;//声明D1类对象d1d1.nV=2;//

使用最远基类成员d1.fun();}61C++语言程序设计62虚基类及其派生类构造函数⚫建立对象时所指定的类称为最(远)派生类。⚫虚基类的成员是由最派生类的构造函数通过调用虚基类的构造函数进行初始化的。⚫在整个继承结构中,直接或间

接继承虚基类的所有派生类,都必须在构造函数的成员初始化表中给出对虚基类的构造函数的调用。如果未列出,则表示调用该虚基类的默认构造函数。⚫在建立对象时,只有最派生类的构造函数调用虚基类的构造函数,该派生类的其他基类对虚基类构造函数的调用被忽略。虚基类C++语言程序

设计63有虚基类时的构造函数举例虚基类#include<iostream.h>classB0//声明基类B0{public://外部接口B0(intn){nV=n;}intnV;voidfun(){cout<<"MemberofB0"<<endl;

}};classB1:virtualpublicB0{public:B1(inta):B0(a){}intnV1;};classB2:virtualpublicB0{public:B2(inta):B0(a){}intnV2;};classD1:publicB1,publicB2{publi

c:D1(inta):B0(a),B1(a),B2(a){}intnVd;voidfund(){cout<<"MemberofD1"<<endl;}};intmain(){D1d1(1);d1.nV=2;d1.fun();}64C++语言程序设计65综合实例⚫例7-10(课后阅读)⚫这个程序有两点

不足:①基类的成员函数pay()的函数体为空,在实现部分仍要写出函数体,显得冗余。②在main()函数中,建立了四个不同类的对象,对它们进行了类似的操作,但是却重复写了四遍类似的语句,程序不够简洁。C++语言程序设计66小结与复习建议⚫主要内容–类的继承、类成员的访问控制、单继承与

多继承、派生类的构造和析构函数、类成员的标识与访问⚫达到的目标–理解类的继承关系,学会使用继承关系实现代码的重用。

小橙橙
小橙橙
文档分享,欢迎浏览!
  • 文档 25747
  • 被下载 7
  • 被收藏 0
相关资源
广告代码123
若发现您的权益受到侵害,请立即联系客服,我们会尽快为您处理。侵权客服QQ:395972555 (支持时间:9:00-21:00) 公众号
Powered by 太赞文库
×
确认删除?