




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、会计学1 C+_面向对象程序设计面向对象程序设计_谭浩强谭浩强 第十一第十一 章章 继承性是面向对象程序设计中最重要的机制继承性是面向对象程序设计中最重要的机制 。这种机制。这种机制提供了无限重复利用程序资源的提供了无限重复利用程序资源的 一种途径一种途径。通过。通过C+语言中的继承机制,语言中的继承机制,可可 以扩充和完善旧的程序设计以适应新的需求以扩充和完善旧的程序设计以适应新的需求 。这样不仅可以节省程序开发的时间和资源这样不仅可以节省程序开发的时间和资源 ,并且为未来程序增添了新的资源。,并且为未来程序增添了新的资源。 第1页/共57页 class Student int num; c
2、har name30; char sex; public: void display( ) /对成员函数对成员函数display的定的定 义义 coutnum: numendl; coutname: nameendl; coutsex: sexendl; ; 第2页/共57页 class Studend1 int num; /此行原来己有此行原来己有 char name20; /此行原来己有此行原来己有 char sex; /此行原来己有此行原来己有 int age; char addr20; public: void display( ) ; /此行原来己有此行原来己有 coutnum: n
3、umendl; /此行原来己有此行原来己有 coutname: nameendl;/此行原来己有此行原来己有 coutsex: sexendl; /此行原来己有此行原来己有 coutage: ageendl; coutaddress: addrendl; ; 第3页/共57页 利用原来定义的类利用原来定义的类StudentStudent作为基础,再加上新的作为基础,再加上新的 内容即可,以减少重复的工作量。内容即可,以减少重复的工作量。 C+C+提供的继提供的继 承机制就是为了解决这个问题。承机制就是为了解决这个问题。 在在C+中所谓中所谓“继承继承”就是在一个已存在的类的就是在一个已存在的类
4、的 基础上建立一个新的类。基础上建立一个新的类。已存在的类称为已存在的类称为“基类基类 (base class)”或或“父类父类(father class)”。新建。新建 立的类称为立的类称为“派生类派生类(derived class)”或或“子类子类 (son class)”。 第4页/共57页 class Student1: public Student/声明基类是声明基类是Student private: int age; /新增加的数据成员新增加的数据成员 string addr; /新增加的数据成员新增加的数据成员 public: void display_1( ) /新增加的成员函
5、数新增加的成员函数 coutage: ageendl; coutaddress: addrendl; ; 第5页/共57页 类类A派生类派生类B:类:类A为基类,类为基类,类B为派生类。为派生类。 A B 新增加的成员新增加的成员 数据和成员函数据和成员函 数数 第6页/共57页 在在C+语言中,语言中,一个派生类可以从一个基类一个派生类可以从一个基类 派生,也可以从多个基类派生。派生,也可以从多个基类派生。从一个基类从一个基类 派生的继承称为单继承;从多个基类派生的派生的继承称为单继承;从多个基类派生的 继承称为多继承。继承称为多继承。 第7页/共57页 通过继承机制,可以利用已有的数据类型
6、来通过继承机制,可以利用已有的数据类型来 定义新的数据类型。定义新的数据类型。所定义的新的数据类型所定义的新的数据类型 不仅拥有新定义的成员,而且还同时拥有旧不仅拥有新定义的成员,而且还同时拥有旧 的成员。的成员。我们称已存在的用来派生新类的类我们称已存在的用来派生新类的类 为基类,又称为父类。为基类,又称为父类。由已存在的类派生出由已存在的类派生出 的新类称为派生类,又称为子类。的新类称为派生类,又称为子类。 第8页/共57页 在建立派生类的过程中,基类不会做任何改在建立派生类的过程中,基类不会做任何改 变,变,派生类则除了继承基类的所有可引用的派生类则除了继承基类的所有可引用的 成员变量和
7、成员函数外,还可另外定义本身成员变量和成员函数外,还可另外定义本身 的成员变量和处理这些变量的函数,的成员变量和处理这些变量的函数,由于派由于派 生类可继承基类的成员变量和成员函数,因生类可继承基类的成员变量和成员函数,因 此在基类中定义好的数据和函数等的程序代此在基类中定义好的数据和函数等的程序代 码可重复使用,这样可以提高程序的可靠性码可重复使用,这样可以提高程序的可靠性 。 第9页/共57页 当从已有的类中派生出新的类时,可以对派生类做以下当从已有的类中派生出新的类时,可以对派生类做以下 几种变化:几种变化: 1、 可以继承基类的成员数据或成员函数。可以继承基类的成员数据或成员函数。 2
8、、可以增加新的成员变量。、可以增加新的成员变量。 3、可以增加新的成员函数。、可以增加新的成员函数。 4、可以重新定义已有的成员函数。、可以重新定义已有的成员函数。 5、可以改变现有的成员属性。、可以改变现有的成员属性。 在在C+中有二种继承:单一继承和多重继承。当一个派生中有二种继承:单一继承和多重继承。当一个派生 类仅由一个基类派生时,称为单一继承;而当一个派生类仅由一个基类派生时,称为单一继承;而当一个派生 类由二个或更多个基类所派生时,称为多重继承。类由二个或更多个基类所派生时,称为多重继承。 第10页/共57页 类类A派生类派生类B:类:类A为基类,类为基类,类B为派生类。为派生类。
9、 A B 但派生并不是简单的扩充,有可能改变基类的性质。但派生并不是简单的扩充,有可能改变基类的性质。 有三种派生方式:公有派生、保护派生、私有派生。有三种派生方式:公有派生、保护派生、私有派生。 class B:public A.; class B:protected A.; class B:private A.; 默认的是私有派生。默认的是私有派生。 class B: A .; A为私有派生为私有派生 第11页/共57页 从一个基类派生一个类的一般格式为:从一个基类派生一个类的一般格式为: class ClassName:BaseClassName private: .; /私有成员说明私
10、有成员说明 public: .; /公有成员说明公有成员说明 protected: .; /保护成员说明保护成员说明 派生类名派生类名 基类名基类名继承方式继承方式 public: 表示公有基类表示公有基类 private:表示私有基类表示私有基类(默认默认) protected:表示保护基类表示保护基类 派生类中新增加的成员派生类中新增加的成员 第12页/共57页 公有派生 class ClassName: public BaseClassName 公有派生时,公有派生时,基类中所有成员在派生类中保持各个成员的访问权限基类中所有成员在派生类中保持各个成员的访问权限。 公有派生,派生类中保持基
11、类的成员特性公有派生,派生类中保持基类的成员特性 基类成员属性基类成员属性派生类中派生类中派生类外派生类外 公有公有可以引用可以引用可以引用可以引用 保护保护可以引用可以引用不可引用不可引用 私有私有不可引用不可引用不可引用不可引用 基类:基类:public: 在派生类和类外可以使用在派生类和类外可以使用 protected: 在派生类中使用在派生类中使用 private: 不能在派生类中使用不能在派生类中使用 第13页/共57页 x(私有私有) y(保护保护) z(公有公有) A( ) Getx() Gety() ShowA() A x(私私有私私有) y(保护保护) z(公有公有) A(
12、) Getx() Gety() ShowA() B m(私有私有) n(私有私有) B() Show() Sum() publi c x在类在类B新增加的成员中不能直新增加的成员中不能直 接调用接调用 y在类在类B中可以调用中可以调用 z在整个文件中可以调用在整个文件中可以调用 对类对类B的对象初始化即是对的对象初始化即是对x,y,z,m,n等全部成员的初始化等全部成员的初始化 第14页/共57页 class A int x; protected: int y; public: int z; A(int a,int b,int c)x=a;y=b;z=c;/基类初始化基类初始化 int Get
13、x()return x;/返回返回x int Gety()return y;/返回返回y void ShowA()cout x=xty=ytz=zn; ; class B:public A int 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(1,2,3,4,5); b1.ShowA(); b1.Show
14、(); cout Sum=b1.Sum()n;coutx=b1.Getx()t; cout y= b1.Gety()t;cout z=b1.zn; 公有派生公有派生 对基类初始化对基类初始化 因为因为x是基类私有,所以在派生类和类外中不能直接引用是基类私有,所以在派生类和类外中不能直接引用 因为因为y是基类保护,所以在是基类保护,所以在 派生类中可以直接引用。而派生类中可以直接引用。而 在类外不可直接引用。在类外不可直接引用。 因为因为z是基类公有,是基类公有, 所以在派生类中和类所以在派生类中和类 外均可直接引用。外均可直接引用。 第15页/共57页 私有派生 class ClassName
15、: private BaseClassName 私有派生时,基类中公有成员和保护成员在派生类中均变为私有的,在派生类中仍可直接使用这些成员,私有派生时,基类中公有成员和保护成员在派生类中均变为私有的,在派生类中仍可直接使用这些成员,基类中的私有成员,在派生类中不可直接使用。基类中的私有成员,在派生类中不可直接使用。 私有派生,派生类中基类公有和保护成员成为私有私有派生,派生类中基类公有和保护成员成为私有 基类成员属性基类成员属性派生类派生类派生类外派生类外 公有公有可以引用可以引用不可引用不可引用 保护保护可以引用可以引用不可引用不可引用 私有私有不可引用不可引用不可引用不可引用 基类:基类:
16、public: (变为私有变为私有)在派生类中使用,类外不可使用在派生类中使用,类外不可使用 protected: (变为私有)在派生类中使用,类外不可使用变为私有)在派生类中使用,类外不可使用 private: 不能在派生类中和类外使用不能在派生类中和类外使用 第16页/共57页 x(私有私有) y(保护保护) z(公有公有) A( ) Getx() Gety() ShowA() A x(私私有私私有) y(私有私有) z(私有私有) A( ) Getx() Gety() ShowA() B m(私有私有) n(私有私有) B() Show() Sum() privat e x在类在类B新增
17、加的成员新增加的成员 中不能直接调用中不能直接调用 y在类在类B中可以调用中可以调用 z在类在类B中可以调用中可以调用 对类对类B的对象初始化即是对的对象初始化即是对x,y,z,m,n等全部成员的初始化等全部成员的初始化 均为私有均为私有 类类B 外不外不 能引用能引用 第17页/共57页 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
18、()cout x=xty=ytz=zn; ; class B:private A int 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(1,2,3,4,5); b1.ShowA(); b1.Show(); cout Sum=b1.Sum()n;coutx=b1.Getx()t; cout y= b1.Ge
19、ty()t;cout z=b1.zn; 私有派生私有派生 对基类初始化对基类初始化 因为因为x是基类私有,所以在派生类和类外中不能直接引用是基类私有,所以在派生类和类外中不能直接引用 y是基类保护,所以在派生是基类保护,所以在派生 类中可以直接引用。而在类类中可以直接引用。而在类 外不可直接引用。外不可直接引用。 z是基类公有,私有是基类公有,私有 派生变为私有,所以派生变为私有,所以 在派生类中可直接引在派生类中可直接引 用,用,而在类外不可。而在类外不可。 这些函数都是基类公有这些函数都是基类公有 ,在类外不可使用。在类外不可使用。 A a1(1,2,3); a1.ShowA(); 第18
20、页/共57页 保护派生 class ClassName: protected BaseClassName 保护派生时,基类中公有成员和保护成员在派生类中均变为保护的和私有的,在派生类中仍可直接使用这些成员,保护派生时,基类中公有成员和保护成员在派生类中均变为保护的和私有的,在派生类中仍可直接使用这些成员,基类中的私有成员,在派生类中不可直接使用。基类中的私有成员,在派生类中不可直接使用。 保护派生,派生类中基类公有和保护成员降级使用保护派生,派生类中基类公有和保护成员降级使用 基类成员属性基类成员属性派生类派生类派生类外派生类外 公有公有可以引用可以引用不可引用不可引用 保护保护可以引用可以引
21、用不可引用不可引用 私有私有不可引用不可引用不可引用不可引用 基类:基类:public: (变为保护变为保护)在派生类中使用,类外不可使用在派生类中使用,类外不可使用 protected: (变为私有)在派生类中使用,类外不可使用变为私有)在派生类中使用,类外不可使用 private: 不能在派生类中和类外使用不能在派生类中和类外使用 第19页/共57页 x(私有私有) y(保护保护) z(公有公有) A( ) Getx() Gety() ShowA() A x(私私有私私有) y(私有私有) z(保护保护) A( ) Getx() Gety() ShowA() B m(私有私有) n(私有私
22、有) B() Show() Sum() protecte d x在类在类B新增加的成员新增加的成员 中不能直接调用中不能直接调用 y在类在类B中可以调用中可以调用 z在类在类B中可以调用中可以调用 对类对类B的对象初始化即是对的对象初始化即是对x,y,z,m,n等全部成员的初始化等全部成员的初始化 均为保护均为保护 类类B 外不外不 能引用能引用 第20页/共57页 protected 成员是一种具有血缘关系内成员是一种具有血缘关系内 外有别的成员。它对派生类的对象而言外有别的成员。它对派生类的对象而言 ,是公开成员,可以访问,对,是公开成员,可以访问,对血缘外部血缘外部 而言,与私有成员一样
23、被隐蔽而言,与私有成员一样被隐蔽。 第21页/共57页 抽象类与保护的成员函数抽象类与保护的成员函数 当定义了一个类,当定义了一个类,这个类这个类只能用作基类只能用作基类来派来派 生出新的类,而不能用这种类来定义对象时生出新的类,而不能用这种类来定义对象时 ,称这种类为抽象类。,称这种类为抽象类。当对某些特殊的对象当对某些特殊的对象 要进行很好地封装时,需要定义抽象类。要进行很好地封装时,需要定义抽象类。 将类的构造函数或析构函数的访问权限将类的构造函数或析构函数的访问权限 定义为定义为保护保护的时,这种类为的时,这种类为抽象类抽象类。 第22页/共57页 当把类中的构造函数或析构函数说明为当
24、把类中的构造函数或析构函数说明为 私有私有的时,所定义的类通常是没有任何的时,所定义的类通常是没有任何 实用意义的,一般情况下,不能用它来实用意义的,一般情况下,不能用它来 产生对象,也不能用它来产生派生类。产生对象,也不能用它来产生派生类。 第23页/共57页 x(私有私有) y(私有私有) A( )(保护保护) ShowA()(公有公有) A x(私私有私私有) y(私私有私私有) A( )(保护保护) ShowA() B m(私有私有) B() Show() public 在类在类B中不能定义中不能定义A的对象的对象 在任何时候都不能定义在任何时候都不能定义A的对象的对象 但可以在初始化
25、类但可以在初始化类B的对象时初始化的对象时初始化原类原类A中的成员中的成员, 因为因为A()在类在类B中是可以被调用的。中是可以被调用的。 第24页/共57页 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 A int m; A a1;/在派生类中也不可以定义在派生类中也不可以定义A的对象,实际上还是类外调用的对象,实际上还是类外调用 public: B(int a,int b,int c):A(a,b)/可以在
26、派生类中调用可以在派生类中调用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) 第25页/共57页 多重继承多重继承 可以用多个基类来派生一个类。可以用多个基类来派生一个类。 A B C D 多重继承是单多重继承是单 一继承的扩展一继承的扩展 派生类中新定义的成员派生类中新定义的成员 第26页/共57页 格式为:格式为: class 类名类名:类名类名1,., 类名
27、类名n private: . ; /私有成员说明私有成员说明; public: . ; /公有成员说明公有成员说明; protected: . ; /保护的成员说明保护的成员说明; ; 继承方式继承方式 class D: public A, protected B, private C ./派生类中新增加成员派生类中新增加成员 ; 第27页/共57页 class Aint x1,y1; public:A(int a,int b) x1=a; y1=b; void ShowA(void) coutA.x=x1tA.y=y1endl; ; class Bint x2,y2; public:B(in
28、t a,int b)x2=a; y2=b; void ShowB(void) coutB.x=x2tB.y=y2endl; ; class C:public A,private B int 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 (); c.ShowB (); 公有派生公有
29、派生私有派生私有派生 仍为公有仍为公有成为私有成为私有 非法,私有类外不可调用非法,私有类外不可调用 B b1(10,20); b1.ShowB(); 第28页/共57页 初始化基类成员初始化基类成员 构造函数不能被继承构造函数不能被继承,派生类的构造函数派生类的构造函数 必须调用基类的构造函数必须调用基类的构造函数来初始化基类来初始化基类 成员基类成员基类子对象子对象。 派生类构造函数的调用顺序如下:派生类构造函数的调用顺序如下: 基类的构造函数基类的构造函数 子对象类的构造函数子对象类的构造函数 派生类的构造函数派生类的构造函数 第29页/共57页 class B:public A int
30、 y; A a1; public: B(int a, int b):A(a),a1(3)y=b; . ; 当撤销派生类对象时,析当撤销派生类对象时,析 构函数的调用正好相反。构函数的调用正好相反。 基类的构造函数基类的构造函数 子对象类的构造函数子对象类的构造函数 派生类的构造函数派生类的构造函数 第30页/共57页 class Base1 int x; public: Base1(int a)x=a;cout调用基类调用基类1的构造函数的构造函数!n; Base1( )cout调用基类调用基类1的析构函数的析构函数!n; ; class Base2 int y; public: Base2(
31、int a)y=a;cout调用基类调用基类2的构造函数的构造函数!n; Base2( )cout调用基类调用基类2的析构函数的析构函数!n; ; class Derived:public Base2, public Base1 int 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的构造函的构造函 数数
32、调用基类调用基类1的构造函的构造函 数数 调用派生类的构造函数调用派生类的构造函数 调用派生类的析构函数调用派生类的析构函数 调用基类调用基类1的析构函数的析构函数 调用基类调用基类2的析构函数的析构函数 先说明基类先说明基类2 第31页/共57页 class Derived:public Base2, public Base1 int 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调用
33、派生类的析构函数调用派生类的析构函数!n; ; void main(void) Derived c(100,200); 基类子对象基类子对象 基类成员构造基类成员构造 基类子对象构造基类子对象构造 基类成员构造用基类名,基类成员构造用基类名, 基类子对象构造用对象名基类子对象构造用对象名 第32页/共57页 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
34、)y=a;cout调用基类调用基类2的构造函数的构造函数!n; Base2( )cout调用基类调用基类2的析构函数的析构函数!n; ; class Derived:public Base2, public Base1 int 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,20
35、0); 第33页/共57页 调用基类调用基类2的构造函数的构造函数 调用基类调用基类1的构造函数的构造函数 调用派生类的构造函数调用派生类的构造函数 调用派生类的析构函数调用派生类的析构函数 调用基类调用基类1的析构函数的析构函数 调用基类调用基类2的析构函数的析构函数 调用基类调用基类1的构造函数的构造函数 调用基类调用基类1的构造函数的构造函数 调用基类调用基类1的析构函数的析构函数 调用基类调用基类1的析构函数的析构函数 说明基类说明基类1的对象的对象b1,b2 第34页/共57页 class Base1 int x; public: Base1(int a); Base1( ); ;
36、class Base2 int y; public: Base2(int a); Base2( ); ; class Derived:public Base2, public Base1 int z; Base1 b1,b2; public: Derived(int a,int b); Derived( ); ; x Base1() Base1() Base1 y Base2() Base2() Base2 Derived x Base1() Base1() y Base2() Base2() x Base1() Base1() b1 x Base1() Base1() b2 z Derive
37、d() Derived 第35页/共57页 冲突冲突 A B C x A() x B() x C() D A() x B() x C() x D() d D v; v.x=5; publi c 派生类对象派生类对象 产生了冲突产生了冲突 A:v.x= 5;用类作用符限定用类作用符限定 第36页/共57页 class A public: int x; void Show()cout x=xn; A(int a=0)x=a; ; class B public: int x; void Show()cout x=xn; B(int a=0)x=a; ; class C:public A,public
38、 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:Show(); 第37页/共57页 支配规则支配规则 A x A() Dpubli c x A() x D() 基类成员基类成员 派生类新增成员
39、派生类新增成员 D v; v.x=5; 当派生类中新增加的数据或当派生类中新增加的数据或 函数与基类中原有的同名时函数与基类中原有的同名时 ,若不加限制,则,若不加限制,则优先调用优先调用 派生类中的成员派生类中的成员。 5 第38页/共57页 class A public:int x; void Show()cout x=xn; ; class B public:int y; void Show()cout y=yn; ; class C:public A,public B public:int y; /类类B和类和类C均有均有y的成员的成员 ; void main(void) C c1;
40、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值值 当派生类中新增加当派生类中新增加 的数据或函数与基的数据或函数与基 类中原有的同名时类中原有的同名时 ,若不加限制,则,若不加限制,则 优先调用派生类中优先调用派生类中 的成员的成员。 第39页/共57页 class A p
41、ublic:int x; A(int a=0) x=a; ; class B public:int y; B(int a=0) y=a; ; class C:public A int 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(); x z Show() a1.x b1.y C的对象所占空间的
42、对象所占空间 从基类从基类A中继承中继承 在类在类C中新说明中新说明 在类在类C中新说明中新说明 在类在类C中新说明中新说明 在类在类C中新说明中新说明 从基类从基类A中继承中继承 新说明类新说明类A对象中的对象中的x 第40页/共57页 基类与对象成员基类与对象成员 任一基类在派生类中只能继承一次,否则,会造任一基类在派生类中只能继承一次,否则,会造 成成员名的冲突成成员名的冲突 若在派生类中,确实要有二个以上基类的成员,若在派生类中,确实要有二个以上基类的成员,则可用则可用 基类的二个对象作为派生类的成员。基类的二个对象作为派生类的成员。 把一个类作为派生类的基类或把一个类的对象作为一个把
43、一个类作为派生类的基类或把一个类的对象作为一个 类的成员,在使用上是有区别的:在派生类中可直接使类的成员,在使用上是有区别的:在派生类中可直接使 用基类的成员(访问权限允许的话),但要用基类的成员(访问权限允许的话),但要使用对象成使用对象成 员的成员时,必须在对象名后加上成员运算符员的成员时,必须在对象名后加上成员运算符 “.”和成员名和成员名。 第41页/共57页 在平面上作两个点,连一直线,求直线的长度和在平面上作两个点,连一直线,求直线的长度和 直线中点的坐标。直线中点的坐标。 基类为基类为Dot,有两个公有数据成员,即平面上的坐,有两个公有数据成员,即平面上的坐 标(标(x,y),同
44、时有构造函数及打印函数。,同时有构造函数及打印函数。 派生类为派生类为Line,有,有两个基类两个基类Dot对象对象,分别存放两,分别存放两 点的坐标,同时,从点的坐标,同时,从基类继承了一个基类继承了一个Dot数据数据,存,存 放直线中点的坐标。放直线中点的坐标。 第42页/共57页 x y Dot(x,y)(构造构造) Dot( Dot(float a=0,float b=0) x=a; y=b; void Show(void)coutx=xty=yendl; ; class Line:public Dot Dot d1,d2; public:Line(Dot dot1,Dot dot2)
45、: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)*(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
46、); Line line(dot1,dot2); line.Showl(); 用坐标初始化用坐标初始化Dot对象对象 在在Line中新说明的成员中新说明的成员对成员初始化对成员初始化 x,y是继承基类的成员是继承基类的成员 打印坐标打印坐标 第44页/共57页 赋值兼容规则赋值兼容规则 基类基类 对象对象 派生类派生类 对象对象 相互之间能否赋值?相互之间能否赋值? 可以将派生类对象的值赋给基类对象。可以将派生类对象的值赋给基类对象。反之不行反之不行 Base b; Derive d; b = d; 只是将从基类只是将从基类继承来的成员继承来的成员赋值。赋值。 第45页/共57页 Show()
47、 Dot( Line line; dot=line; line=dot; 非法非法 第46页/共57页 可以将一个派生类对象的地址赋给基类的指针变可以将一个派生类对象的地址赋给基类的指针变 量。量。 基类对象基类对象 派生类对象派生类对象 Base b; Derive d; Base *basep; base p basep= base p basep = Base basei= 基类对象基类对象 派生类对象派生类对象 Base b; Derive d; 别名别名basei basei只能引用只能引用 从基类继承来从基类继承来 的成员。的成员。基类引用基类引用 派生类对象派生类对象 第48页/
48、共57页 class A public:int x; A(int a=0) x=a; ; class B public: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=a1.xendl;coutb1.y=b1.yendl; c1.S
49、how();a1=c1;b1=c1;/派生类对象向基类对象赋值派生类对象向基类对象赋值 couta1.x=a1.xendl;coutb1.y=b1.yShow(); x A( ) y B( ) z C( ) Show( ) 10 20 50 a1.x=100 b1.y=200 x=10y=20 z=50a1.x=10 b1.y=20 c1 x A( ) a1 y B( ) b1 10 0 20 0 10 20 错误!错误! 第49页/共57页 虚基类虚基类 类类B 是类是类A的派生类的派生类 x A() x A() y B() x A() z C() A类类 B类类C类类 dx D() x A() z C() y B() A() x D类类 类类A拷贝拷贝 类类C 是类是类A的派生类的派生类 类类D 是类是类B和类和类C的派生类的派生类 这样,类这样,类D中就有两份类中就有两份类A的拷贝的拷贝 B类类 C类类 类类A拷贝拷贝 第50页/共57页 这种同一个公共的基类这种同一个公共的基类 在派生类中产生多个拷在派生类中产生多个拷 贝,不仅多占用了存储贝,不仅多占用了存储 空间,空间,而且可能会造成而且可能会造成 多个拷贝中的数据不一多个拷贝中的数据
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 美容产品线上直播带货企业制定与实施新质生产力项目商业计划书
- 自动化修理解决方案创新创业项目商业计划书
- 生产现场布局咨询服务创新创业项目商业计划书
- 绘画艺术品线上拍卖平台企业制定与实施新质生产力项目商业计划书
- 城市规划师日常工作内容及职责
- 企业信息化系统操作手册
- 小学数学三角形单元总复习题集
- 小学英语期中测试卷及听力练习题
- 聚氨酯防水材料施工工艺与质量管控
- 【期末试卷】2021-2022学年湖南省邵东市高二上学期期末语文试题(解析版)
- 秦皇岛职业技术学院工作人员招聘考试真题2022
- 信息安全实训系统用户手册
- 2023年成人学位英语高频词汇
- 樊登读书会市级分会运营手册OK
- 车辆装卸运输规定(2篇)
- GB/T 11376-2020金属及其他无机覆盖层金属的磷化膜
- 卫生医疗机构消毒培训教学课件
- 心血管疾病介入诊疗技术规范
- 陈明主讲中医妇科经验方
- 毕业论文:电气自动化技术毕业论文
- 教改项目项目结项汇报
评论
0/150
提交评论