C++多继承

2016-02-19 18:35 4 1 收藏

关注图老师设计创意栏目可以让大家能更好的了解电脑,知道有关于电脑的更多有趣教程,今天给大家分享C++多继承教程,希望对大家能有一点小小的帮助。

【 tulaoshi.com - 编程语言 】


  多继续可以看作是单继续的扩展。所谓多继续是指派生类具有多个基类,派生类与每个基类之间的关系仍可看作是一个单继续。
  
  多继续下派生类的定义格式如下:
  
  class 派生类名:继续方式1基类名1,继续方式2基类名2,…
   {
  派生类类体
   };
  
  其中,继续方式1,继续方式2,…是三种继续方式:public、private、protected之一。例如:
  
  class A
  {
  …
  };
  class B
  {
  …
  };
  class C : public A, public, B
  {
  …
  };
  
  其中,派生类C具有两个基类(类A和类B),因此,类C是多继续的。按照继续的规定,派生类C的成员包含了基类B中成员以及该类本身的成员。
  
  多继续的构造函数
  
  在多继续的情况下,派生类的构造函数格式如下:
  
  派生类名(总参数表):基类名1(参数表1),基类名2(参数表2),…
   子对象名(参数表n+1),…
  {
   派生类构造函数体
  }
  
  其中,总参数表中各个参数包含了其后的各个分参数表。
  
  多继续下派生类的构造函数与单继续下派生类构造函数相似,它必须同时负责该派生类所有基类构造函数的调用。同时,派生类的参数个数必须包含完成所有基类初始化所需的参数个数。
  
  派生类构造函数执行顺序是先执行所胡基类的构造函数,再执行派生类本身构造函数,处于同一层次的各基类构造函数的执行顺序取决于定义派生类时所指定的各基类顺序,与派生类构造函数中所定义的成员初始化列表的各项顺序无关。也就是说,执行基类构造函数的顺序取决于定义派生类时基类的顺序。可见,派生类构造函数的成员初始化列表中各项顺序可以任意地排列。
   
  下面通过一个例子来说明派生类构造函数的构成及其执行顺序。
  
  #include
  class B1
  {
  public:
  B1(int i)
  {
  b1 = i;
  cout"构造函数 B1."   }
  void print() { cout   private:
  int b1;
  };
  
  class B2
  {
  public:
  B2(int i)
  {
  b2 = i;
  cout"构造函数 B2."   }
  void print() { cout   private:
  int b2;
  };
  
  class B3
  {
  public:
  B3(int i)
  {
  b3 = i;
  cout"构造函数 B3."   }
  int getb3() { return b3; }
  private:
  int b3;
  };
  class A : public B2, public B1
  {
  public:
  A(int i, int j, int k, int l):B1(i), B2(j), bb(k)
  {
  a = l;
  cout"构造函数 A."   }
  void print()
  {
  B1::print();
  B2::print();
  cout }
  private:
  int a;
  B3 bb;
  };
  
  void main()
  {
  A aa(1, 2, 3, 4);
  aa.print();
  }
  
  该程序的输出结果为:
  
   构造函数 B2.2
  
   构造函数 B1.1
  
   构造函数 B3.3
  
   构造函数 A.4
  
   1
  
   2
  
   4, 3
  
  在该程序中,作用域运算符::用于解决作用域冲突的问题。在派生类A中的print()函数的定义中,使用了B1::print;和B2::print();语句分别指明调用哪一个类中的print()函数,这种用法应该学会。
  
  二义性问题
  
  一般说来,在派生类中对基类成员的访问应该是唯一的,但是,由于多继续情况下,可能造成对基类中某成员的访问出现了不唯一的情况,则称为对基类成员访问的二义性问题。
  
  实际上,在上例已经出现过这一问题,回忆一下上例中,派生类A的两基类B1和B2中都有一个成员函数print()。假如在派生类中访问print()函数,到底是哪一个基类的呢?于是出现了二义性。但是在上例中解决了这个问题,其办法是通过作用域运算符::进行了限定。假如不加以限定,则会出现二义性问题。
  
  下面再举一个简单的例子,对二义性问题进行深入讨论。例如:
  
  class A
  {
  public:
  void f();
  };
  
  class B
  {
  public:
  void f();
  void g();
  };
  
  class C : public A, public B
  {
  public:
  void g();
  void h();
  };
  
  假如定义一个类C的对象c1:
  
   C c1;
  
  则对函数f()的访问
  
   c1.f();
  
  便具有二义性:是访问类A中的f(),还是访问类B中的f()呢?
  
  解决的方法可用前面用过的成员名限定法来消除二义性,例如:
  
   c1.A::f();
  
  或者
  
   c1.B::f();
  
  
     但是,最好的解决办法是在类C中定义一个同名成员f(),类C中的f()再根据需要来决定调用A::f(),还是B::f(),还是两者皆有,这样,c1.f()将调用C::f()。
  
  同样地,类C中成员函数调用f()也会出现二义性问题。例如:
  
  viod C::h()
   {
  f();
   }
  
  这里有二义性问题,该函数应修改为:
  
   void C::h()
   {
  A::f();
   }
  
  或者
  
   void C::h()
   {
  B::f();
   }
  
  或者
  
   void C::f()
   {
  A::f();
  B::f();
   }
  
  另外,在前例中,类B中有一个成员函数g(),类C中也有一个成员函数g()。这时,
  
   c1.g();
  
  不存在二义性,它是指C::g(),而不是指B::g()。因为这两个g()函数,一个出现在基类B,一个出现在派生类C,规定派生类的成员将支配基类中的同名成员。因此,上例中类C中的g()支配类B中的g(),不存在二义性,可选择支配者的那个名字。
  
  当一个派生类从多个基类派生类,而这些基类又有一个共同的基类,则对该基类中说明的成员进行访问时,也可能会出现二义性。例如:
  
  class A
  {
  public:
  int a;
  };
  class B1 : public A
  {
  private:
  int b1;
  };
  class B2 : public A
  {
  private:
  int b2;
  };
  class C : public B1, public B2
  {
  public:
  int f();
  private:
  int c;
  };
  
  已知:C c1;
  
  下面的两个访问都有二义性:
  
  c1.a;
  c1.A::a;
  
  而下面的两个访问是正确的:
  
  c1.B1::a;
  c1.B2::a;
  
  类C的成员函数f()用如下定义可以消除二义性:
  
  int C::f()
   {
  retrun B1::a + B2::a;
   }
  
  由于二义性的原因,一个类不可以从同一个类中直接继续一次以上,例如:
  
  class A : public B, public B
   {
  …
   }
  
  这是错误的。
  
  
  

来源:http://www.tulaoshi.com/n/20160219/1618228.html

延伸阅读
C++中,成员指针是最为复杂的语法结构。但在事件驱动和多线程应用中被广泛用于调用回叫函数。在多线程应用中,每个线程都通过指向成员函数的指针来调用该函数。在这样的应用中,如果不用成员指针,编程是非常困难的。 刚遇到这种语法时也许会让你止步不前。但你会发现,使用恰当的类型定义之后,复杂的语法是可以简化的。本文引导你了解成...
本试题仅用于考查C++/C程序员的基本编程技能。内容限于C++/C常用语法,不涉及数据结构、算法以及深奥的语法。考试成绩能反映出考生的编程质量以及对C++/C的理解程度,但不能反映考生的智力和软件开发能力。 笔试时间90分钟。请考生认真答题,切勿轻视。 一、请填写BOOL , float, 指针变量 与零值比较的 if 语句。(10分) ...
下面的是学C++时要注重的。 1.把C++当成一门新的语言学习(和C没啥关系!真的。); 2.看《Thinking In C++》,不要看《C++变成死相》; 3.看《The C++ Programming Language》和《Inside The C++ Object Model》,不要因为他们很难而我们自己是初学者所以就不看; 4.不要被VC、BCB、BC、MC、TC等词汇所迷惑——他...
标签: 计算机语言
要点1: 很多C++程序员还在使用而不是用更新的标准的库。这两者都有什么不同呢?首先,5年前我们就开始反对把.h符号继续用在标准的头文件中。继续使用过时的规则可不是个好的方法。从功能性的角度来讲,包含了一系列模板化的I/O类,相反地只仅仅是支持字符流。另外,输入输出流的C++标准规范接口在一些微妙的细节上都已改进,因此,和在接...
   持久对象 (persistent objects)广泛应用于游戏、分布式数据库系统、多媒体以及图形应用程序中。目前C++并不直接支持持久性(persistence)(但有一些在C++未来版本中添加持久性和反射(reflection)的建议)。 !-- frame contents -- !-- /frame contents -- 持久对象可以在创建它的程序的作用域之外保持自身状态。...

经验教程

386

收藏

84
微博分享 QQ分享 QQ空间 手机页面 收藏网站 回到头部