欢迎来到淘文阁 - 分享文档赚钱的网站! | 帮助中心 好文档才是您的得力助手!
淘文阁 - 分享文档赚钱的网站
全部分类
  • 研究报告>
  • 管理文献>
  • 标准材料>
  • 技术资料>
  • 教育专区>
  • 应用文书>
  • 生活休闲>
  • 考试试题>
  • pptx模板>
  • 工商注册>
  • 期刊短文>
  • 图片设计>
  • ImageVerifierCode 换一换

    第七章 继承和派生.doc

    • 资源ID:60117864       资源大小:51KB        全文页数:6页
    • 资源格式: DOC        下载积分:20金币
    快捷下载 游客一键下载
    会员登录下载
    微信登录下载
    三方登录下载: 微信开放平台登录   QQ登录  
    二维码
    微信扫一扫登录
    下载资源需要20金币
    邮箱/手机:
    温馨提示:
    快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。
    如填写123,账号就是123,密码也是123。
    支付方式: 支付宝    微信支付   
    验证码:   换一换

     
    账号:
    密码:
    验证码:   换一换
      忘记密码?
        
    友情提示
    2、PDF文件下载后,可能会被浏览器默认打开,此种情况可以点击浏览器菜单,保存网页到桌面,就可以正常下载了。
    3、本站不支持迅雷下载,请使用电脑自带的IE浏览器,或者360浏览器、谷歌浏览器下载即可。
    4、本站资源下载后的文档和图纸-无水印,预览文档经过压缩,下载后原文更清晰。
    5、试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。

    第七章 继承和派生.doc

    第七章 继承和派生一、 基类和派生类1. 在C+中,可以从一个类派生出另一个类,前者称为基类或父类,后者称为派生类或子类。一个派生类可以从一个或多个基类派生。从一个基类派生的继承称单继承,从多个基类派生的继承称多继承。2. 单继承定义格式: class 派生类:继承方式 基类 派生类新定义成员; ; 其中,“派生类”是从“基类”按指定的“继承关系”派生出的、新定义的一个类的名字。“继承方式”有三种:(1)public 公有继承 (2)private 私有继承 (3) protected 保护继承3. 多继承定义格式: class 派生类:继承方式1 基类1,继承方式2 基类2, 派生类新定义成员; ;4. 公有继承:当派生类的继承方式是public继承时,基类的public和protected成员的访问属性在派生类中保持不变,而基类的private成员不可访问,即基类的public和protected成员分别作为派生类的public和protected成员,派生类的其他成员可以直接访问它们。 例1: class B private: int x; protected: int y; public: int z; ; class A:public B private: int a; protected: int b; public: int c; A a; (1) 类B是基类,有3个数据成员x、y、z,分别是private、protected、public属性。类A是派生类,有3个数据成员a、b、c,分别是private、protected、public属性。由于类A是从类B公有派生的,类B中的public、protected属性的成员可继承到类A中来,且保持原来的属性。故类A中有5个数据成员,即a、b、c、y。(2) 可以通过类A的对象a直接访问public成员,即z和c,并不能访问a、b、y数据成员。 (3) 不考虑派生类时,类中的private和protected属性的成员都可以被类的成员函数访问,而都不能被该类的对象直接访问。在派生类中,当公有继承时,基类中protected属性的成员可以作为派生类的protected属性的成员,而private属性的成员不能作为派生类的成员。5. 保护继承:当派生类的继承方式是protected继承时,基类的public和protected成员可以被继承到派生类中,但访问属性都变成protected,而基类的private成员不可访问,即基类的public和protected成员都作为派生类的protected成员,派生类的其他成员可以直接访问它们。例2: class B private: int x; protected: int y; public: int z; ; class A:protected B private: int a; protected: int b; public: int c; A a;类B是基类,有3个数据成员x、y、z,分别是private、protected、public属性。类A是从类B保护派生的,类B中的protected、public属性的成员可继承到类A中,均变成protected属性。故类A中有5个数据成员,即a、b、c、y、z。可以通过类A的对象a直接访问public成员,即c,不能访问a、b、y、z数据成员。6. 私有继承:当派生类的继承方式是private继承时,基类的public和protected成员可以被继承到派生类中,但访问属性都变成private,而基类的private成员不可访问,即基类的public和protected成员都作为派生类的private成员,派生类的其他成员可以直接访问它们。例3: class B private: int x; protected: int y; public: int z; ; class A:private B private: int a; protected: int b; public: int c; A a;类B是基类,有3个数据成员x、y、z,分别是private、protected、public属性。类A是从类B私有派生的,类B中的protected、public属性的成员可继承到类A中,均变成private属性。故类A中有5个数据成员,即a、b、c、y、z。可以通过类A的对象a直接访问public成员,即c,不能访问a、b、y、z数据成员。二、 单继承1. 在单继承中,每个类可以有多个派生类,但是每个派生类只能有一个基类,从而形成树形结构。2. 构造函数不能被继承,故派生类的构造函数必须通过调用基类的构造函数来初始化基类子对象。在定义派生类的构造函数时,除了要对自己的数据成员进行初始化,还要调用基类构造函数使基类的数据成员得以初始化。若派生类中还有子对象,应包含对子对象初始化的构造函数。3. 派生类构造函数一般格式: 派生类名(派生类构造函数总参数表):基类构造函数(参数表1), 子对象名(参数表2) 派生类中数据成员初始化; ;4. 派生类构造函数调用顺序:(1)基类的构造函数;(2)子对象类的构造函数(有的话);(3)派生类构造函数。例4: class A public: A() cout<<”A Constructor”<<endl; ; class B:public A public: B() cout<<”B Constructor”<<endl; ; void main() B b; 执行结果为: A Constructor B Constructor5. 当对象被删除时,派生类的析构函数被执行。析构函数也不能被继承,故在执行派生类的析构函数时,基类的析构函数也将被调用。析构函数的执行顺序是先执行派生类的析构函数,再执行基类的析构函数。例5: class A public: A() cout<<”A Constructor”<<endl; A() cout<<”A Destructor”<<endl; ; class B:public A public: B() cout<<”B Constructor”<<endl; B() cout<<”B Destructor”<<endl; ; void main() B b; 执行结果为: A Constructor B Constructor B Destructor A Destructor6. 派生类构造函数的定义中可以省略对基类构造函数的调用,条件是在基类中必须有默认的构造函数或根本没有定义构造函数。7. 当基类的构造函数使用一个或多个参数时,则派生类必须定义构造函数,提供将参数传递给基类构造函数的途径。有的情况下,派生类构造函数的函数体可能为空,仅起到参数传递的作用。三、 多继承1. 多继承是指派生类具有多个基类,派生类和每个基类间的关系仍可看作一个单继承。 如: class A ; class B; class C:public A,public B ; 其中派生类C具有两个基类,故为多继承。派生类C的成员包含了基类A和基类B中的成员和它本身的成员。2. 多继承派生类的构造函数格式: 派生类名(总参数表):基类名1(参数表1),基类名2(参数表2), 基类名n(参数表n),子对象名(参数表n+1) 派生类构造函数体; 其中,“总参数表”中各个参数包含了其后的各个分参数表。3. 多继承和单继承派生类的构造函数必须同时负责该派生类所有基类构造函数的调用,且派生类的参数个数必须包含完成所有基类初始化所需的参数个数。4. 多继承派生类构造函数的执行顺序:(1)调用基类的构造函数,调用次序按照它们被继承时说明的次序(从左到右)。(2)调用子对象的构造函数,调用次序按照它们在类中说明的次序。(3)调用派生类的构造函数。5. 对于处于同一层次的各基类构造函数的执行顺序取决于定义派生类时所指定的各基类顺序,与派生类构造函数中所定义的成员初始化列表中的各项顺序无关。 例6: class A int a; public: A(int i) a=i; cout<<”A Constructor”<<endl; void disp() cout<<”a=”<<a<<endl; ; class B int b; public: B(int j) b=j; cout<<”B Constructor”<<endl; void disp() cout<<”b=”<<b<<endl; ; class C:public B,public A int c; public: c(int k):A(k-2):B(k+2) c=k; cout<<”C Constructor”<<endl; void disp() A:disp(); B:disp(); cout<<”c=”<<c<<endl; ; void main() C obj(10); obj.disp(); 执行结果为:B Constructor A Constructor C Constructor a=8 b=12 c=106. 多继承中析构函数的执行顺序与构造函数的顺序正好相反。7. 在派生类中对基类成员的访问应该是唯一的,但在多继承下,可能造成对基类中某个成员的访问出现了不唯一的情况,称为对基类成员访问的二义性问题。一般解决方法是采用作用域运算符:。四、 虚基类1. 虚基类说明格式: virtual 继承方式 基类 其中,virtual是虚基类的关键字。虚基类的说明用在定义派生类时,写在派生类名后面。例7: class x protected: int a; public: x() a=10; ; class x1:public x public: x1() cout<<a<<endl; ;class x2:public x public: x2()cout<<a<<endl; ;class y:x1,x2 public: y() cout<<a<<endl; /二义性,是x1:a还是x2:a ;void main() y obj; 此时,通过引入虚基类消除二义性。引入虚基类后,派生类的对象中只存在一个虚基类的子对象。当一个类有虚基类时,编译系统将为该类的对象定义一个指针成员,让它指向虚基类的子对象。该指针叫虚基类指针。上面程序应改为: class x1:virtual public x public: x1() cout<<a<<endl; ;class x2:virtual public x public: x2()cout<<a<<endl; ;2. 虚基类的初始化和多继承类的语法一样,但调用派生类构造函数的顺序应遵守以下原则: (1)虚基类的构造函数在非虚基类前调用。(2)若同一层次中包含多个虚基类,则虚基类的构造函数按它们说明的顺序调用。(3)若虚基类由非虚基类派生而来,则仍先调用基类构造函数,再调用派生类中构造函数的执行顺序。例7: class base1 public: base1() cout<<”class base1”<<endl; ; class base2 public: base2() cout<<”class base2”<<endl; ; class level1:public base2,virtual public base1public: level1() cout<<”class level1”<<endl; ; class level2:public base2,virtual public base1public: level2() cout<<”class level2”<<endl; ; class toplevel:public level1,virtual public level2public: toplevel () cout<<”class toplevel”<<endl; ; void main() toplevel obj; 整个obj对象的各构造函数的执行顺序为: base1()、base2()、level2()、base2()、level1()、toplevel(). 执行结果为: class base1 class base2 class level2 class base2 class level1 class toplevel 3. 一般,当定义虚基类的构造函数时,虚基类只允许定义不带参数的或带默认参数的构造函数。五、 模板和继承1. 类模板可以从类模板中派生,此时两个类模板的类型参数有关联关系。在定义派生类时必须指定这个类模板的类型参数。例8: template <class T> class A public: void dispa(T obj) cout<<obj<<endl; ; template <class T1,class T2> class B:public A<T2> public:void dispb(T1 obj1,T2 obj2) cout<<obj1<<”<<obj2<<endl; ; void main() B<char *,double> obj1; obj1.dispa(12.34); obj1.dispb(“The value is:”56.78); B<int,int> obj2; obj2.dispb(89,10); B<double,char *> obj3; obj3.disp(2.3,”is OK.”); B<char,char *> obj4; obj4.dispb(I,”and you”); 执行结果: 12.34 The value is:56.78 89 10 2.3 is OK. I and you2. 类模板可以从非类模板中派生,此时模板继承非模板的成员,再从类模板实例化模板类,最后从该模板类实例化成对象。 例9: class A int x; public: A(int i) x=i; int getx() return x; void disp() cout<<x<<endl; ; template <class T> class B:public A T y; public: B(T a,int j):A(j) y=a; T gety() return y; void disp() cout<<y<<”<<getx()<<endl; ;void main() A obj(123); obj.disp(); B<int> obj1(1,2); B<double> obj2(1.3,5); B<char *> obj3(“It is”,10); B<char> obj4(=,20);obj1.disp(); obj2.disp(); obj3.disp(); obj4.disp(); 执行结果: 123 1 2 1.3 5 It is 10 =203. 非类模板可以从类模板中派生,此时必须在非模板类中指定基模板类(即将类模板实例化成模板类),再从该非模板类实例化成对象。例10: class A protected: T x; public: A<T>(T i) x=i; ;class B:public A<int> int y; public: B(int i,int j):A<int>(i) y=j; void disp() cout<<”x=”<<x<<”,y=”<<y<<endl; ; void main() B obj(1,2); obj.disp(); 执行结果: x=1,y=2习题 1. C+中的类有两种用法:一种是类的实例化,即生成类的对象,并参与系统的运行;另一种是通过( )派生出新的类。 2. 继承具有( )性,即当基类本身也是某一个类的派生类时,底层的派生类也会自动继承间接基类的成员。 3. 在多继承中,公有派生和私有派生对于基类成员在派生类中的可访问性与单继承的规则( )。 4. 派生可分为( )和( )。由( )得到得派生类,其基类的所有公有成员都只能成为它的私有成员,这些私有成员只能被派生类的成员函数访问,而通过( )无权访问它;( )的意义是基类中所有公有成员在派生类中也都是公有的。 5. 基类的( )不能为派生类的成员访问,基类的( )在派生类中的性质和继承的性质一样,而基类的( )在私有继承时在派生类中成为私有成员,在公有和保护继承时在派生类中仍为保护对象。 6. ( )提供了类对外部的界面,( )只能被类的成员访问,而( )不允许外界访问,但允许派生类的成员访问,这样既有一定的隐藏能力,又提供了开放的界面。 7. 若类A和类B定义如下:( )是非法的表达式。 class A int I,j; public: void get(); / ; class B:A int k; public: void make(); / ; void B:make() k=i*j; 8. 派生类的对象对它的基类成员中( )继承的( )成员是可以访问的。 9. 设置虚基类的目的是( )。 10. 对于派生类的构造函数,在定义对象时构造函数的执行顺序为:先执行( ),再执行( ),后执行( )。 11. 下面说法错误的是( )。 A. 一个派生类可以作为另一个派生类的基类 B. 派生类至少有一个基类 C. 派生类的成员除了它自己的成员外,还包含了它的基类的成员 D. 派生类中继承的基类成员的访问权限到派生类保持不变 12. 下面描述错误的是( )。 A. 派生类是基类的具体化 B. 派生类是基类的子集 C. 派生类是基类定义的延续 D. 派生类是基类的组合 13. 派生类的构造函数的成员初始化列表中,不能包含( )。 A. 基类的构造函数 B. 派生类中子对象的初始化 C. 基类的子对象初始化 D. 派生类中一般数据成员的初始化 14. 关于多继承二义性的描述,错误的是( )。 A. 一个派生类的两个基类中都有某个同名成员,在派生类中对这个成员的访问可能出 现二义性 B. 解决二义性的做常用方法是对成员名的限定 C. 基类和派生类中出现同名函数,也存在二义性问题 D. 一个派生类是从两个基类派生来的,而这两个基类又有一个共同的基类,对该基类成员进行访问时,也可能出现二义性 15. 以下程序的执行结果为( )。 class A public: A(int i,int j) a=i; b=j; void move() int x,int y a+=x; b+=y; void show() cout<<”(”<<a<<”,”<<b<<”)”<<endl; private: int a,b; ; class B:public A public: B(int i,int j,int k,int l):A(i,j),x(k),y(l) void show() cout<<x<<”,”<<y<<endl; void fun()move(3,5); void f1() A:show(); private: int x,y; ; void main() A e(1,2); e.show(); B d(3,4,5,6); d.fun(); d.A:show(); d.B:show(); d.f1(); 16. 阅读程序回答问题。class A public: void f1(); A() i1=10; j1=11; protected: int j1; private: int i1; ; class B:protected A public: void f2(); B() i2=20; j2=21; protected: int j2; private: int i2; ;class C:protected B public: void f3(); c() i3=30;j3=31; protected: int j3; private: int i3; ;(1) 派生类B中成员函数f2()能否访问基类A中的成员f1()、i1和j1?(2) 派生类B的对象b能否访问基类A中的成员f1()、i1、j1?(3) 派生类C中成员函数f3()能否访问直接基类B中得成员f2()和j2?能否访问间接基类A中的成员f1()、j1和i1?(4) 派生类C的对象c能否访问直接基类B中的成员f2()、i2和j2?能否访问间接基类A中得成员f1()、j1和i1?17. 指出下面程序的错误并改正。 class A protected: int n,m; public: void A:set(int a,int b) m=a; n=b;void A:show() cout<<m<<”,”<<n<<endl; ;class B:public A int s; public: void B:sets s=m*n;void B:show() cout<<s<<endl; ; void main() B b; b.set(4,5); b.show(); b.sets(); b.show(); 习题参考答案: 1. 继承 2. 传递 3. 完全相同 4. 公有派生 私有派生 私有派生 派生类的对象 公有派生5. 私有成员 公有成员 保护成员 6. 公有成员 私有成员 保护成员7. k=i*j; 8. 公有 公有 9. 消除二义性10. 基类的构造函数 成员对象的构造函数 派生类本身的构造函数11. D。分析:只有在公有继承方式时,派生类中继承的访问属性为public、protected基类成员到派生类后访问属性保持不变。12. B。分析:在派生类中除了继承基类的成员外,还可以添加新的成员。13. C 14. C 15. (1,2) (6,9) 5,6 (6,9)16. (1)可以访问f1()和j1,不能访问i1。 (2)不可以访问f1(),也不能访问i1和j1。 (3)可以访问f2()和j2,也能访问f1()和j1,不能访问i2和i1。 (4)不可以访问f2()和f1(),其它的也都不能访问。17. 由于派生类B中有一个同名的成员函数show(),在执行b.show()时总是执行B类的成员函数,故出错。修改方法是把B类的成员函数show()函数改成shows()。void B:shows() cout<<s<<endl; ; void main() B b; b.set(4,5); b.show(); b.sets(); b.shows();

    注意事项

    本文(第七章 继承和派生.doc)为本站会员(飞****2)主动上传,淘文阁 - 分享文档赚钱的网站仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知淘文阁 - 分享文档赚钱的网站(点击联系客服),我们立即给予删除!

    温馨提示:如果因为网速或其他原因下载失败请重新下载,重复下载不扣分。




    关于淘文阁 - 版权申诉 - 用户使用规则 - 积分规则 - 联系我们

    本站为文档C TO C交易模式,本站只提供存储空间、用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。本站仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知淘文阁网,我们立即给予删除!客服QQ:136780468 微信:18945177775 电话:18904686070

    工信部备案号:黑ICP备15003705号 © 2020-2023 www.taowenge.com 淘文阁 

    收起
    展开