第十一章继承和派生类_第1页
第十一章继承和派生类_第2页
第十一章继承和派生类_第3页
第十一章继承和派生类_第4页
第十一章继承和派生类_第5页
已阅读5页,还剩54页未读 继续免费阅读

下载本文档

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

文档简介

1、第十一章 继承和派生类继承性是面向对象程序设计中最重要的机制。继承性是面向对象程序设计中最重要的机制。这种机制这种机制提供了无限重复利用程序资源的一提供了无限重复利用程序资源的一种途径种途径。通过。通过C+语言中的继承机制,语言中的继承机制,可以可以扩充和完善旧的程序设计以适应新的需求。扩充和完善旧的程序设计以适应新的需求。这样不仅可以节省程序开发的时间和资源,这样不仅可以节省程序开发的时间和资源,并且为未来程序增添了新的资源。并且为未来程序增添了新的资源。class Student int num; char name30; char sex; public: void display( )

2、 /对成员函数对成员函数display的定义的定义 coutnum: numendl; coutname: nameendl; coutsex: sexendl; ;class Studend1 int num; /此行原来己有此行原来己有 char name20; /此行原来己有此行原来己有 char sex; /此行原来己有此行原来己有 int age; char addr20; public: void display( ) ; /此行原来己有此行原来己有 coutnum: numendl; /此行原来己有此行原来己有 coutname: nameendl;/此行原来己有此行原来己有 c

3、outsex: sexendl; /此行原来己有此行原来己有 coutage: ageendl; coutaddress: addrendl; ; 利用原来定义的类利用原来定义的类StudentStudent作为基础,再加上新的作为基础,再加上新的内容即可,以减少重复的工作量。内容即可,以减少重复的工作量。 C+ C+提供的继提供的继承机制就是为了解决这个问题。承机制就是为了解决这个问题。 在在C+中所谓中所谓“继承继承”就是在一个已存在的类的基就是在一个已存在的类的基础上建立一个新的类。础上建立一个新的类。已存在的类称为已存在的类称为“基类基类(base class)”或或“父类父类(fat

4、her class)”。新建立。新建立的类称为的类称为“派生类派生类(derived class)”或或“子类子类(son class)”。 class Student1: public Student/声明基类是声明基类是Studentprivate: int age; /新增加的数据成员新增加的数据成员 string addr; /新增加的数据成员新增加的数据成员public: void display_1( ) /新增加的成员函数新增加的成员函数 coutage: ageendl; coutaddress: addrendl; ;类类A派生类派生类B:类:类A为基类,类为基类,类B为派生

5、类。为派生类。AB新增加的成员数新增加的成员数据和成员函数据和成员函数在在C+语言中,语言中,一个派生类可以从一个基类一个派生类可以从一个基类派生,也可以从多个基类派生。派生,也可以从多个基类派生。从一个基类从一个基类派生的继承称为单继承;从多个基类派生的派生的继承称为单继承;从多个基类派生的继承称为多继承。继承称为多继承。通过继承机制,可以利用已有的数据类型来通过继承机制,可以利用已有的数据类型来定义新的数据类型。定义新的数据类型。所定义的新的数据类型所定义的新的数据类型不仅拥有新定义的成员,而且还同时拥有旧不仅拥有新定义的成员,而且还同时拥有旧的成员。的成员。我们称已存在的用来派生新类的类

6、我们称已存在的用来派生新类的类为基类,又称为父类。为基类,又称为父类。由已存在的类派生出由已存在的类派生出的新类称为派生类,又称为子类。的新类称为派生类,又称为子类。在建立派生类的过程中,基类不会做任何改在建立派生类的过程中,基类不会做任何改变,变,派生类则除了继承基类的所有可引用的派生类则除了继承基类的所有可引用的成员变量和成员函数外,还可另外定义本身成员变量和成员函数外,还可另外定义本身的成员变量和处理这些变量的函数,的成员变量和处理这些变量的函数,由于派由于派生类可继承基类的成员变量和成员函数,因生类可继承基类的成员变量和成员函数,因此在基类中定义好的数据和函数等的程序代此在基类中定义好

7、的数据和函数等的程序代码可重复使用,这样可以提高程序的可靠性。码可重复使用,这样可以提高程序的可靠性。当从已有的类中派生出新的类时,可以对派生类做以下几当从已有的类中派生出新的类时,可以对派生类做以下几种变化:种变化:1、 可以继承基类的成员数据或成员函数。可以继承基类的成员数据或成员函数。2、可以增加新的成员变量。、可以增加新的成员变量。3、可以增加新的成员函数。、可以增加新的成员函数。4、可以重新定义已有的成员函数。、可以重新定义已有的成员函数。5、可以改变现有的成员属性。、可以改变现有的成员属性。在在C+中有二种继承:单一继承和多重继承。当一个派生中有二种继承:单一继承和多重继承。当一个

8、派生类仅由一个基类派生时,称为单一继承;而当一个派生类类仅由一个基类派生时,称为单一继承;而当一个派生类由二个或更多个基类所派生时,称为多重继承。由二个或更多个基类所派生时,称为多重继承。类类A派生类派生类B:类:类A为基类,类为基类,类B为派生类。为派生类。AB但派生并不是简单的扩充,有可能改变基类的性质。但派生并不是简单的扩充,有可能改变基类的性质。有三种派生方式:公有派生、保护派生、私有派生。有三种派生方式:公有派生、保护派生、私有派生。class B:public A.; class B:protected A.; class B:private A.; 默认的是私有派生。默认的是私有

9、派生。class B: A .; A为私有派生为私有派生从一个基类派生一个类的一般格式为:从一个基类派生一个类的一般格式为:class ClassName:BaseClassName private: .; /私有成员说明私有成员说明 public: .; /公有成员说明公有成员说明 protected: .; /保护成员说明保护成员说明 派生类名派生类名基类名基类名继承方式继承方式public: 表示公有基类表示公有基类private:表示私有基类表示私有基类(默认默认)protected:表示保护基类表示保护基类派生类中新增加的成员派生类中新增加的成员公有派生class ClassName

10、: public BaseClassName公有派生时,公有派生时,基类中所有成员在派生类中保持各个成员的访问权限基类中所有成员在派生类中保持各个成员的访问权限。公有派生,派生类中保持基类的成员特性公有派生,派生类中保持基类的成员特性基类成员属性基类成员属性派生类中派生类中派生类外派生类外公有公有可以引用可以引用可以引用可以引用保护保护可以引用可以引用不可引用不可引用私有私有不可引用不可引用不可引用不可引用基类:基类:public: 在派生类和类外可以使用在派生类和类外可以使用protected: 在派生类中使用在派生类中使用private: 不能在派生类中使用不能在派生类中使用x(私有私有)

11、y(保护保护)z(公有公有)A( )Getx()Gety()ShowA()Ax(私私有私私有)y(保护保护)z(公有公有)A( )Getx()Gety()ShowA()Bm(私有私有)n(私有私有)B()Show()Sum()publicx在类在类B新增加的成员中不能直新增加的成员中不能直接调用接调用y在类在类B中可以调用中可以调用z在整个文件中可以调用在整个文件中可以调用对类对类B的对象初始化即是对的对象初始化即是对x,y,z,m,n等全部成员的初始等全部成员的初始化化class A int x;protected: int y;public: int z; A(int a,int b,in

12、t c)x=a;y=b;z=c;/基类初始化基类初始化 int Getx()return x; /返回返回x int Gety()return y; /返回返回y void ShowA()cout x=xty=ytz=zn;class B:public Aint m,n;public: B(int a,int b,int c,int d,int e):A(a,b,c)m=d;n=e; void Show()cout“m=mt“n=nn; coutx=Getx()ty=ytz=zn; int Sum()return ( Getx()+y+z+m+n); ;void main(void) B b1

13、(1,2,3,4,5); b1.ShowA(); b1.Show(); cout Sum=b1.Sum()n;coutx=b1.Getx()t; cout y= b1.Gety()t;cout z=b1.zn;公有派生公有派生对基类初始化对基类初始化因为因为x是基类私有,所以在派生类和类外中不能直接引用是基类私有,所以在派生类和类外中不能直接引用因为因为y是基类保护,所以在是基类保护,所以在派生类中可以直接引用。而派生类中可以直接引用。而在类外不可直接引用。在类外不可直接引用。因为因为z是基类公有,是基类公有,所以在派生类中和类所以在派生类中和类外均可直接引用。外均可直接引用。私有派生clas

14、s ClassName: private BaseClassName私有派生时,基类中公有成员和保护成员在派生类中均变为私有的,在派生类中仍可直私有派生时,基类中公有成员和保护成员在派生类中均变为私有的,在派生类中仍可直接使用这些成员,接使用这些成员,基类中的私有成员,在派生类中不可直接使用。基类中的私有成员,在派生类中不可直接使用。私有派生,派生类中基类公有和保护成员成为私有私有派生,派生类中基类公有和保护成员成为私有基类成员属性基类成员属性派生类派生类派生类外派生类外公有公有可以引用可以引用不可引用不可引用保护保护可以引用可以引用不可引用不可引用私有私有不可引用不可引用不可引用不可引用基类

15、:基类:public: (变为私有变为私有)在派生类中使用,类外不可使用在派生类中使用,类外不可使用protected: (变为私有)在派生类中使用,类外不可使用变为私有)在派生类中使用,类外不可使用private: 不能在派生类中和类外使用不能在派生类中和类外使用x(私有私有)y(保护保护)z(公有公有)A( )Getx()Gety()ShowA()Ax(私私有私私有)y(私有私有)z(私有私有)A( )Getx()Gety()ShowA()Bm(私有私有)n(私有私有)B()Show()Sum()privatex在类在类B新增加的成员新增加的成员中不能直接调用中不能直接调用y在类在类B中可

16、以调用中可以调用z在类在类B中可以调用中可以调用对类对类B的对象初始化即是对的对象初始化即是对x,y,z,m,n等全部成员的初始化等全部成员的初始化均为私有均为私有类类B 外不外不能引用能引用class A int x;protected: int y;public: int z; A(int a,int b,int c)x=a;y=b;z=c;/基类初始化基类初始化 int Getx()return x; /返回返回x int Gety()return y; /返回返回y void ShowA()cout x=xty=ytz=zn;class B:private Aint m,n;publi

17、c: B(int a,int b,int c,int d,int e):A(a,b,c)m=d;n=e; void Show()cout“m=mt“n=nn; coutx=Getx()ty=ytz=zn; int Sum()return ( Getx()+y+z+m+n); ;void main(void) B b1(1,2,3,4,5); b1.ShowA(); b1.Show(); cout Sum=b1.Sum()n;coutx=b1.Getx()t; cout y= b1.Gety()t;cout z=b1.zn;私有派生私有派生对基类初始化对基类初始化因为因为x是基类私有,所以在派生

18、类和类外中不能直接引用是基类私有,所以在派生类和类外中不能直接引用y是基类保护,所以在派生是基类保护,所以在派生类中可以直接引用。而在类类中可以直接引用。而在类外不可直接引用。外不可直接引用。z是基类公有,私有是基类公有,私有派生变为私有,所以派生变为私有,所以在派生类中可直接引在派生类中可直接引用,用,而在类外不可。而在类外不可。这些函数都是基类公有,这些函数都是基类公有,在类外不可使用。在类外不可使用。A a1(1,2,3); a1.ShowA();保护派生class ClassName: protected BaseClassName保护派生时,基类中公有成员和保护成员在派生类中均变为保

19、护的和私有的,在派生类保护派生时,基类中公有成员和保护成员在派生类中均变为保护的和私有的,在派生类中仍可直接使用这些成员,中仍可直接使用这些成员,基类中的私有成员,在派生类中不可直接使用。基类中的私有成员,在派生类中不可直接使用。保护派生,派生类中基类公有和保护成员降级使用保护派生,派生类中基类公有和保护成员降级使用基类成员属性基类成员属性派生类派生类派生类外派生类外公有公有可以引用可以引用不可引用不可引用保护保护可以引用可以引用不可引用不可引用私有私有不可引用不可引用不可引用不可引用基类:基类:public: (变为保护变为保护)在派生类中使用,类外不可使用在派生类中使用,类外不可使用pro

20、tected: (变为私有)在派生类中使用,类外不可使用变为私有)在派生类中使用,类外不可使用private: 不能在派生类中和类外使用不能在派生类中和类外使用x(私有私有)y(保护保护)z(公有公有)A( )Getx()Gety()ShowA()Ax(私私有私私有)y(私有私有)z(保护保护)A( )Getx()Gety()ShowA()Bm(私有私有)n(私有私有)B()Show()Sum()protectedx在类在类B新增加的成员新增加的成员中不能直接调用中不能直接调用y在类在类B中可以调用中可以调用z在类在类B中可以调用中可以调用对类对类B的对象初始化即是对的对象初始化即是对x,y,

21、z,m,n等全部成员的初始化等全部成员的初始化均为保护均为保护类类B 外不外不能引用能引用protected 成员是一种具有血缘关系内成员是一种具有血缘关系内外有别的成员。它对派生类的对象而言,外有别的成员。它对派生类的对象而言,是公开成员,可以访问,对是公开成员,可以访问,对血缘外部而血缘外部而言,与私有成员一样被隐蔽言,与私有成员一样被隐蔽。抽象类与保护的成员函数抽象类与保护的成员函数当定义了一个类,当定义了一个类,这个类这个类只能用作基类只能用作基类来派来派生出新的类,而不能用这种类来定义对象时,生出新的类,而不能用这种类来定义对象时,称这种类为抽象类。称这种类为抽象类。当对某些特殊的对

22、象要当对某些特殊的对象要进行很好地封装时,需要定义抽象类。进行很好地封装时,需要定义抽象类。将类的构造函数或析构函数的访问权限将类的构造函数或析构函数的访问权限定义为定义为保护保护的时,这种类为的时,这种类为抽象类抽象类。 当把类中的构造函数或析构函数说明为当把类中的构造函数或析构函数说明为私有私有的时,所定义的类通常是没有任何的时,所定义的类通常是没有任何实用意义的,一般情况下,不能用它来实用意义的,一般情况下,不能用它来产生对象,也不能用它来产生派生类。产生对象,也不能用它来产生派生类。 x(私有私有)y(私有私有)A( )(保护保护)ShowA()(公有公有)Ax(私私有私私有)y(私私

23、有私私有)A( )(保护保护)ShowA()Bm(私有私有)B()Show()public在类在类B中不能定义中不能定义A的对象的对象在任何时候都不能定义在任何时候都不能定义A的对象的对象但可以在初始化类但可以在初始化类B的对象时初始化的对象时初始化原类原类A中的成员中的成员,因为因为A()在类在类B中是可以被调用的。中是可以被调用的。class A int x, y;protected: A(int a,int b)x=a;y=b;/基类初始化基类初始化public:void ShowA()cout x=xty=yn;class B: public Aint m;A a1;/在派生类中也不可

24、以定义在派生类中也不可以定义A的对象,实际上还是类外调用的对象,实际上还是类外调用public: B(int a,int b,int c):A(a,b)/可以在派生类中调用可以在派生类中调用A的构造函数的构造函数 m=c; void Show() cout“m=mn; ShowA(); ;void main(void) B b1(1,2,3); /可以定义派生类对象可以定义派生类对象 b1.Show(); A aa;/不可定义不可定义A的对象的对象 a1(4,5)多重继承多重继承可以用多个基类来派生一个类。可以用多个基类来派生一个类。ABCD多重继承是单多重继承是单一继承的扩展一继承的扩展派生

25、类中新定义的派生类中新定义的成员成员格式为:格式为:class 类名类名:类名类名1,., 类名类名n private: . ; /私有成员说明私有成员说明; public: . ; /公有成员说明公有成员说明; protected: . ; /保护的成员说明保护的成员说明;继承方式继承方式class D: public A, protected B, private C ./派生类中新增加成员派生类中新增加成员;class Aint x1,y1;public: A(int a,int b) x1=a; y1=b;void ShowA(void) coutA.x=x1tA.y=y1endl;

26、;class Bint x2,y2;public: B(int a,int b)x2=a; y2=b; void ShowB(void) coutB.x=x2tB.y=y2endl; ;class C:public A,private Bint x,y;public: C(int a,int b,int c,int d,int e,int f):A(a,b),B(c,d) x=e; y=f; void ShowC(void)coutC.x=xtC.y=yendl;ShowA();ShowB();void main(void)C c(1,2,3,4,5,6);c.ShowC();c.ShowA

27、();c.ShowB ();公有派生公有派生私有派生私有派生仍为公有仍为公有成为私有成为私有非法,私有类外不可调用非法,私有类外不可调用B b1(10,20);b1.ShowB();初始化基类成员初始化基类成员构造函数不能被继承构造函数不能被继承,派生类的构造函数派生类的构造函数必须调用基类的构造函数必须调用基类的构造函数来初始化基类来初始化基类成员基类成员基类子对象子对象。派生类构造函数的调用顺序如下:派生类构造函数的调用顺序如下:基类的构造函数基类的构造函数子对象类的构造函数子对象类的构造函数派生类的构造函数派生类的构造函数class B:public A int y; A a1;publ

28、ic: B(int a, int b):A(a),a1(3)y=b; .;当撤销派生类对象时,析当撤销派生类对象时,析构函数的调用正好相反。构函数的调用正好相反。基类的构造函数基类的构造函数子对象类的构造函数子对象类的构造函数派生类的构造函数派生类的构造函数class Base1 int x;public: Base1(int a)x=a;cout调用基类调用基类1的构造函数的构造函数!n;Base1( )cout调用基类调用基类1的析构函数的析构函数!n; ;class Base2 int y;public: Base2(int a)y=a;cout调用基类调用基类2的构造函数的构造函数!n

29、;Base2( )cout调用基类调用基类2的析构函数的析构函数!n; ;class Derived:public Base2, public Base1int z;public: Derived(int a,int b):Base1(a),Base2(20) z=b; cout调用派生类的构造函数调用派生类的构造函数!n;Derived( )cout调用派生类的析构函数调用派生类的析构函数!n;void main(void)Derived c(100,200);调用基类调用基类2的构造函数的构造函数调用基类调用基类1的构造函数的构造函数调用派生类的构造函数调用派生类的构造函数调用派生类的析构

30、函数调用派生类的析构函数调用基类调用基类1的析构函数的析构函数调用基类调用基类2的析构函数的析构函数先说明基类先说明基类2class Derived:public Base2, public Base1int z; Base1 b1,b2; public: Derived(int a,int b):Base1(a),Base2(20), b1(200),b2(a+b) z=b; cout调用派生类的构造函数调用派生类的构造函数!n; Derived( )cout调用派生类的析构函数调用派生类的析构函数!n;void main(void)Derived c(100,200);基类子对象基类子对象

31、基类成员构造基类成员构造基类子对象构造基类子对象构造基类成员构造用基类名,基类成员构造用基类名,基类子对象构造用对象名基类子对象构造用对象名class Base1 int x;public: Base1(int a)x=a;cout调用基类调用基类1的构造函数的构造函数!n;Base1( )cout调用基类调用基类1的析构函数的析构函数!n; ;class Base2 int y;public: Base2(int a)y=a;cout调用基类调用基类2的构造函数的构造函数!n;Base2( )cout调用基类调用基类2的析构函数的析构函数!n; ;class Derived:public B

32、ase2, public Base1int z; Base1 b1,b2; public: Derived(int a,int b):Base1(a),Base2(20), b1(200),b2(a+b) z=b; cout调用派生类的构造函数调用派生类的构造函数!n;Derived( )cout调用派生类的析构函数调用派生类的析构函数!n;void main(void)Derived c(100,200);调用基类调用基类2的构造函数的构造函数调用基类调用基类1的构造函数的构造函数调用派生类的构造函数调用派生类的构造函数调用派生类的析构函数调用派生类的析构函数调用基类调用基类1的析构函数的析

33、构函数调用基类调用基类2的析构函数的析构函数调用基类调用基类1的构造函数的构造函数调用基类调用基类1的构造函数的构造函数调用基类调用基类1的析构函数的析构函数调用基类调用基类1的析构函数的析构函数说明基类说明基类1的对象的对象b1,b2class Base1 int x;public: Base1(int a);Base1( );class Base2 int y;public: Base2(int a);Base2( );class Derived:public Base2, public Base1int z; Base1 b1,b2; public: Derived(int a,int

34、b);Derived( );xBase1()Base1()Base1yBase2()Base2()Base2DerivedxBase1()Base1()yBase2()Base2()xBase1()Base1()b1xBase1()Base1()b2zDerived()Derived冲突冲突ABCxA()xB()xC()DA()xB()xC()xD()dD v;v.x=5;public派生类对象派生类对象产生了冲突产生了冲突A:v.x=5;用类作用符限定用类作用符限定class Apublic: int x; void Show()cout x=xn; A(int a=0)x=a;class

35、Bpublic: int x; void Show()cout x=xn; B(int a=0)x=a;class C:public A,public Bint y;public: void Setx(int a) x=a; /c1对象中有两个对象中有两个x成员成员 void Sety(int b)y=b; int Gety() return y;void main(void)C c1;c1.Show(); /c1对象中有两个对象中有两个Show()函数函数 这时,可以利用这时,可以利用类作用域符类作用域符:来来指明数据或函数的来源。指明数据或函数的来源。如:如:A:x=a; c1.B:Sho

36、w();支配规则支配规则AxA()DpublicxA()xD()基类成员基类成员派生类新增成员派生类新增成员D v;v.x=5;当派生类中新增加的数据或当派生类中新增加的数据或函数与基类中原有的同名时,函数与基类中原有的同名时,若不加限制,则若不加限制,则优先调用派优先调用派生类中的成员生类中的成员。5class Apublic: int x;void Show()cout x=xn;class Bpublic: int y;void Show()cout y=yn;class C:public A,public Bpublic: int y; /类类B和类和类C均有均有y的成员的成员;voi

37、d main(void) C c1; c1.x=100; c1.y=200;/给派生类中的给派生类中的y赋值赋值 c1.B:y=300;/给基类给基类B中的中的y赋值赋值 c1.A:Show(); c1.B:Show();/用作用域运算符限定调用的函数用作用域运算符限定调用的函数 cout y=c1.yn;/输出派生类中的输出派生类中的y值值 cout y=c1.B:yn; /输出基类输出基类B中的中的y值值当派生类中新增加的当派生类中新增加的数据或函数与基类中数据或函数与基类中原有的同名时,若不原有的同名时,若不加限制,则加限制,则优先调用优先调用派生类中的成员派生类中的成员。class A

38、public: int x;A(int a=0) x=a;class Bpublic: int y;B(int a=0) y=a;class C:public Aint z;B b1; A a1;public: C(int a,int b,int m):A(a),b1(b),a1(a+b) z=m; void Show( )coutx=xt;couty=b1.yt;coutx=zn;couta1.x=a1.xendl; ;void main(void)C c1(100,200,500);c1.Show();xzShow()a1.xb1.yC的对象所占空间的对象所占空间从基类从基类A中继承中继承

39、在类在类C中新说明中新说明在类在类C中新说明中新说明在类在类C中新说明中新说明在类在类C中新说明中新说明从基类从基类A中继承中继承新说明类新说明类A对象中的对象中的x基类与对象成员基类与对象成员任一基类在派生类中只能继承一次,否则,会造任一基类在派生类中只能继承一次,否则,会造成成员名的冲突成成员名的冲突 若在派生类中,确实要有二个以上基类的成员,若在派生类中,确实要有二个以上基类的成员,则可用基则可用基类的二个对象作为派生类的成员。类的二个对象作为派生类的成员。把一个类作为派生类的基类或把一个类的对象作为一个类把一个类作为派生类的基类或把一个类的对象作为一个类的成员,在使用上是有区别的:在派

40、生类中可直接使用基的成员,在使用上是有区别的:在派生类中可直接使用基类的成员(访问权限允许的话),但要类的成员(访问权限允许的话),但要使用对象成员的使用对象成员的成员时,必须在对象名后加上成员运算符成员时,必须在对象名后加上成员运算符“.”和和成员名成员名。在平面上作两个点,连一直线,求直线的长度和在平面上作两个点,连一直线,求直线的长度和直线中点的坐标。直线中点的坐标。基类为基类为Dot,有两个公有数据成员,即平面上的坐,有两个公有数据成员,即平面上的坐标(标(x,y),同时有构造函数及打印函数。,同时有构造函数及打印函数。派生类为派生类为Line,有,有两个基类两个基类Dot对象对象,分

41、别存放两,分别存放两点的坐标,同时,从点的坐标,同时,从基类继承了一个基类继承了一个Dot数据数据,存,存放直线中点的坐标。放直线中点的坐标。xyDot(x,y)(构造构造)Dot(&dot)(拷贝拷贝)Show()Dot的对象空间的对象空间x(中点中点)y(中点中点)Dot(x,y)Dot(&dot)Show()d1xyDot(x.y)Dot(&dot)Show()d2xyDot(x,y)Dot(&dot)Show()Line(dot1,dot2)Showl()Line对象对象空间空间从基类从基类继承继承基类基类对象对象class Dotpublic: flo

42、at x,y;Dot(float a=0,float b=0) x=a; y=b;void Show(void)coutx=xty=yendl;class Line:public DotDot d1,d2;public: Line(Dot dot1,Dot dot2):d1(dot1),d2(dot2) x=(d1.x+d2.x)/2; y=(d1.x+d2.y)/2; void Showl(void) coutDot1: ; d1.Show(); coutDot2: ; d2.Show(); coutLength=sqrt(d1.x-d2.x)*(d1.x-d2.x)+(d1.y-d2.y)

43、*(d1.y-d2.y)endl; coutCenter: x=xty=yendl;void main(void) float a,b; coutab; Dot dot1(a,b);/调用调用Dot的构造函数的构造函数 coutab; Dot dot2(a,b); Line line(dot1,dot2); line.Showl();用坐标初始化用坐标初始化Dot对象对象在在Line中新说明的成员中新说明的成员对成员初始化对成员初始化x,y是继承基类的成员是继承基类的成员打印坐标打印坐标 赋值兼容规则赋值兼容规则基类基类对象对象派生类派生类对象对象 相互之间能否赋值?相互之间能否赋值? 可以将

44、派生类对象的值赋给基类对象。可以将派生类对象的值赋给基类对象。反之不行反之不行Base b;Derive d; b = d; 只是将从基类只是将从基类继承来的成员继承来的成员赋值。赋值。Show()Dot(&dot)Dot(x,y)yxDot的对象空间的对象空间Show()Dot(&dot)Dot(x,y)Show()Dot(&dot)Dot(x,y)yDot(&dot)Show()Dot(x.y)yxxShowl()Line()d2d1yxLine的对象的对象空间空间从基类继从基类继承承基类对基类对象象Dot dot;Line line;dot=line;li

45、ne=dot;非法非法可以将一个派生类对象的地址赋给基类的指针变可以将一个派生类对象的地址赋给基类的指针变量。量。基类对象基类对象派生类对象派生类对象Base b;Derive d;Base *basep;basepbasep=&b;basepbasep = &dbasep只能引只能引用从基类继承用从基类继承来的成员。来的成员。基类指针基类指针派生类对象派生类对象基类对象基类对象派生类对象可以初始化基类的引用。派生类对象可以初始化基类的引用。Derive d;Base basei=&d;基类对象基类对象派生类对象派生类对象Base b;Derive d;别名别名base

46、ibasei只能引用只能引用从基类继承来从基类继承来的成员。的成员。基类引用基类引用派生类对象派生类对象class Apublic: int x;A(int a=0) x=a;class Bpublic: int y;B(int a=0) y=a;class C:public A,public B int z;public: C(int a,int b,int m): A(a), B(b) z=m; void Show( )coutx=xt;couty=yt;coutz=zn;void main(void)A a1(100);B b1(200);C c1(10,20,50);couta1.x=

47、a1.xendl;coutb1.y=b1.yendl;c1.Show();a1=c1; b1=c1;/派生类对象向基类对象赋值派生类对象向基类对象赋值couta1.x=a1.xendl;coutb1.y=b1.yShow();xA( ) yB( )zC( )Show( )102050a1.x=100b1.y=200 x=10y=20z=50a1.x=10b1.y=20c1xA( )a1yB( )b11002001020错误!错误!虚基类虚基类 类类B 是类是类A的派生类的派生类xA()xA()yB()xA()zC()A类类B类类C类类dxD()xA()zC()yB()A()xD类类类类A拷贝拷贝类类C 是类是类A的派生类的派生类类类D 是类是类B和类和类C的派生类的派生类这样,类这样,类D中就有两份类中就有两份类A的拷贝的拷贝B类类C类类类类A拷贝拷贝这种同一个公共的基类这种同一个公共的基类在派生类中产生多个拷在派生类中产生多个拷贝,不仅多占用了存储贝,不仅多占用了存储空间,空间,而且可能会造成而且可能会造成多个拷贝中的数据不一多个拷贝中的数据不一致致 和模糊的引用和模糊的引用。D d;d.x=10; /模糊引用模糊引用dxD()xA()z

温馨提示

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

评论

0/150

提交评论