C++课件第十一章继承和派生类.ppt

上传人:牧羊曲112 文档编号:6154047 上传时间:2023-09-30 格式:PPT 页数:40 大小:344.50KB
返回 下载 相关 举报
C++课件第十一章继承和派生类.ppt_第1页
第1页 / 共40页
C++课件第十一章继承和派生类.ppt_第2页
第2页 / 共40页
C++课件第十一章继承和派生类.ppt_第3页
第3页 / 共40页
C++课件第十一章继承和派生类.ppt_第4页
第4页 / 共40页
C++课件第十一章继承和派生类.ppt_第5页
第5页 / 共40页
点击查看更多>>
资源描述

《C++课件第十一章继承和派生类.ppt》由会员分享,可在线阅读,更多相关《C++课件第十一章继承和派生类.ppt(40页珍藏版)》请在三一办公上搜索。

1、第十一章 继承和派生类,类是一种抽象数据类型,是对具有共同属性和行为的对象(事物)的抽象描述。,顶层的抽象事物具有处于底层的抽象事物的共同特征,而处于底层的抽象事物除了包含顶层抽象事物的特征外,还具有自身的我特征。,一个类继承另一个类时,这个类被称为继承类、派生类或子类,另一个类被称为被继承类、基类或父类。继承类包含了被继承类中的所有成员,且有自己的成员。,继承:从一个或多个先前定义过的类(称为基类)中接受全部或一部分数据(属性)或函数(行为或操作),并且补充定义新的数据或函数,因而形成一个新的低层的类(称为派生类)。而该派生类还可用作更低层派生类的基类。,class demo protect

2、ed:int j;public:demo()j=0 void add(int i)j+=i;void display()coutjendl;;,1 派生类定义的格式,class child:public demo public:void sub(int i)j-=i;,void main(void)child object,object1;object.display();object.add(10);object.display();object.sub(5);object.display();object1.display;,0,10,5,0,定义派生类的基本格式:class 派生类名:继

3、承权限 基类名继承权限:public,protected,private影响的是被继承的原基类成员的访问权限class定义的默认为private,struct定义的默认为public,继承权限为public时,称该派生为公有派生。基类中的所有public成员在派生类中仍是public成员,所有protected成员在派生类中仍是protected成员。继承权限为private时,称该派生为私有派生。基类中的public成员和protected成员在派生类中均变成private成员。继承权限为protected时,称该派生为保护派生。基类中的public成员和protected成员在派生类中均变

4、成protected成员。,无论哪一种继承权限,其基类的private成员均不能为派生类所继承。但可通过被同时继承下来的原基类的某些函数间接访问它们。,private:aa1protected:aa2public:aa3,A,Class B:public A private:bb1 protected:bb2 public:bb3,private:bb1protected:aa2 bb2public:aa3 bb3,B,公有派生,private:aa1protected:aa2public:aa3,A,Class B:protected A private:bb1 protected:bb2

5、public:bb3,private:bb1protected:aa2 bb2 aa3public:bb3,B,保护派生,private:aa1protected:aa2public:aa3,A,Class B:A private:bb1 protected:bb2 public:bb3,private:bb1 aa2 aa3protected:bb2 public:bb3,B,私有派生,2 派生类的使用,#include class employee private:char*name;short age;float salary;public:employee()name=0;age=0;

6、salary=0.0;employee(char*name1,short age1,float salary1)name=new charstrlen(name1)+1;strcpy(name,name1);age=age1;salary=salary1;,void print()const/const成员函数:不能改变类中成 员数据的值,也不能调用类中非 const成员函数 cout“name:”name;cout“age:”age;cout“salary:”salaryendl;employee()delete name;,Manager:除具有employee的属性外,有新的属性。为避免

7、重复定义,可从employee中派生出manager(派生类)。,class manager:public employee private:int level;public:manager()level=0;manager(char*name1,short age1,float salary1,int level1):employee(name1,age1,salary1)level=level1;void print_level()cout“level:”levelendl;,派生类构造函数:使用初始化符表初始化基类中的成员。,缺省构造函数若基类无缺省构造函数,将出错,void main(

8、)manager m(“xyz,24,1000,2);m.print_level();m.print();m.employee:print();,void main()manager n;n.print_level();n.print();,若a是Y从X类中继承来的公用成员,设y是Y的一个对象,则可访问y.a或y.X:a,protected 访问指明符:外部函数不能访问;派生类成员函数可直接访问。class employee private:short age;float salary;protected:char*name;/;,派生类成员函数:void manager:print_name

9、()const coutnameendl;,外部函数:void f()manager m;coutm.nameendl;/错,继续派生:class director:public manager/,employee,多层继承,class x protected:int i,j;public:x(int i,int j)x:i=i,x:j=j;void print()cout i=i j=j endl;,class y:public xint k;public:y(int i,int j):x(i,j)k=i*j;/初始化列表void print()cout i=i j=j k=kendl;,支

10、配规则(就近原则),class z:public y public:z(int i,int j):y(i,j)/初始化列表void print1()cout i=i j=jendl;void print()y:print();,void main()y y1(23,45);y1.print();y1.x:print();z z1(10,20);z1.print();z1.print1();z1.y:print();z1.x:print();,i=23 j=45 k=1035,i=23 j=45,i=10 j=20 k=200,i=10 j=20,i=10 j=20 k=200,i=10 j=2

11、0,对属于基类的成员进行初始化是通过初始表中的初始化项来初始化的。若初始化表中没有调用基类的初始化项,则自动调用基类的无参构造函数进行初始化。如果派生类的自有成员和继承成员同名,则自有成员优先,即通过这个共同的成员名所访问的是自有成员,而不是继承成员,这种情况下,可以在成员名前加类区分符将同名成员区分开。(支配规则)作用域运算符不能连续使用,即下列形式是不允许的:CName1:Cname2:Cnamen 作用域运算符的左操作数可以是当前对象的直接基类,也可以是当前对象的间接基类(祖先类)。,3 多重继承与冲突,由多个基类派生出一个子类称之为多重继承在多重派生中,如果不同的基类具有名字相同的共有

12、成员或保护成员,此时若在派生类中不正确使用它们,就会产生二义性,这种情况称之为冲突,【例】冲突的程序示例。class A protected:int x;public:A(int a)x=a;void Show(void)coutx=xn;class B protected:int x;public:B(int a)x=a;void Show(void)coutx=xn;,class C:public A,public B/多重继承 int y;public:C(int a,int b):A(a),B(b)/多重继承的初始化/void Setx(int a)/x=a;/冲突 A:x=a;/正确

13、(冲突的解决办法:在成员名 前加上基类名)void Sety(int b)y=b;int Gety(void)return y;,void main(void)C c1(10,100);/c1.Show();/冲突 c1.B:Show();/正确,class B1 protected:int x;public:void Show()coutx=xn;class B2 protected:int x;public:void Show()coutx=xn;,class D1:public B1;class D2:public B2;class C:public D2,public D1 publi

14、c:/void Setx1(int a)D1:B1:x=a;/错误,域运算 符不能连续使用 void Setx1(int a)D1:x=a;/正确,或为B1:x=a;void Setx2(int a)D2:x=a;/正确,或为B2:x=a;,void main(void)C c;c.Setx1(2);/c.D1:B1:Show();/错误,域运算符不能连续使用 c.SetX2(3);c.D2:Show();/正确,或为c.B2:Show();,4 构造、析构函数的调用顺序,构造函数的调用顺序只与派生类继承基类的顺序有关,而与初始化成员列表中构造函数顺序无关。一个类的构造函数只能对它的直接基类的

15、构造函数传递实参。,派生类所不能继承的:,5 访问类型的调整,有时为了某种目的,需要将从派生类继承的内容的访问类型进行调整,这时可以通过访问声明进行。访问声明的一般格式为::;其中,必须基类的public和protected类型的成员名。在访问声明时仅仅说明基类成员名,即对成员数据不可以为它说明数据类型,对成员函数不可以说明参数和返回值类型。,【例】用访问声明调整访问类型class Cbaseint x;protected:int y;public:int Fun(int a,int b)return a;class CDerived:Cbase protected:/int CBase:y;

16、/错误,数据成员的访问声明中不能有类型 CBase:y;/正确 public:/int CBase:Fun(int,int);/错误,成员函数的访问声明不 能有参数和返回值类型 CBase:Fun;/正确;,访问声明不允许在派生类中改变基类成员的访问类型,即基类中的protected成员在派生类中只能调整为protected类型,基类中的public成员在派生类中只能调整为public类型。对基类中重载函数进行访问声明,将会调整基类中所有具有该名的函数的访问类型。如果在派生类中有与基类中同名的函数,也允许在派生类中对该函数进行访问声明。,6 赋值兼容规则,赋值兼容规则是指,在具有继承关系的类之

17、间:1.公有派生类对象可直接赋值给基类的对象2.基类对象不可以赋给派生类对象3.公有派生类对象的地址可赋给基类指针变量4.公有派生类对象可以初始化基类引用5.在将公有派生类的对象赋给基类对象之后,基类对象只能访问派生类中从基类继承的公有成员,不能访问派生类中增加的公有成员。,【例】赋值兼容规则class Cbase protected:int x;public:CBase(int a)x=a;void Show1()coutx=xn;class CDerived:public Cbase protected:int y;public:CDerived(int a,int b):CBase(b)

18、y=a;void Show1()couty=yn;void Show2()couty=yn;,void main()Cderived c(2,3);Cbase b1(4),*b2;Cbase/错误,理由同上,7 虚基类,基类A被一个派生类D多次继承,类D产生两个类A的副本。,(virtual),虚基类的类层次,虚基类的基本思想是:当将一个基类声明为虚基类时,不管它在派生类中被继承多少次,该基类中的成员在该派生类中始终都只有一个拷贝(即所有派生类均共享基类成员)。虚基类通过关键字Virtual实现。,class A private:int x;public:void setx(int a)x=a

19、;void getx()coutxendl;class B:public A;class C:public A;class D:public B,public C;void main()D m;m.B:setx(3);m.B:getx();m.C:setx(4);m.C:getx();/m.A:setx(5);/会产生冲突/m.A:getx();/会产生冲突,非虚基类继承,3,4,class A private:int x;public:void setx(int a)x=a;void getx()coutxendl;class B:virtual public A;/定义虚基类class C

20、:virtual public A;/定义虚基类class D:public B,public C;void main()D m;m.B:setx(3);m.B:getx();m.C:setx(4);m.C:getx();m.A:setx(5);m.A:getx();/不会产生冲突 m.setx(6);m.getx();,虚基类继承,3,4,5,6,派生类调用虚基类的构造函数的方法与调用一般基类的构造函数的方法是不同的。由虚基类经过一次或多次派生出来的派生类,在其每一个派生类的构造函数的成员初始化列表中必须给出对虚基类的构造函数的调用;如果未列出,则调用虚基类缺省的构造函数。在这种情况下,在虚

21、基类的定义中必须有缺省的构造函数。,class A public:int x;A(int a=0)x=a;class B:virtual public A public:B(int a,int b):A(b).class C:public virtual A public:C(int a,int b):A(b).,class D:public B,public C public:D(int a,int b,int c,int d,int e):B(a,b),C(c,d)/a.,由于类A有缺省的构造函数,所以行a可以不列出类A的构造函数调用。但若类A构造函数改为 A(int a)x=a;,则行a编译会出错!此时必须给出对类A的构造函数调用,如:D(int a,int b,int c,int d,int e):B(a,b),C(c,d),A(100),课后练习:试卷汇编 P17T8 P24T29 P26T10 P33T30 P33T5 P43T10,

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 生活休闲 > 在线阅读


备案号:宁ICP备20000045号-2

经营许可证:宁B2-20210002

宁公网安备 64010402000987号