现在的位置: 首页 > 综合 > 正文

虚继承防止多重继承产生的二义性问题

2018年04月13日 ⁄ 综合 ⁄ 共 1460字 ⁄ 字号 评论关闭

  虚基类:有virtual关键字的类。

    class base

    class derived1 : virutal public base

    class derived2 : virtual public base

    class derived3 : public derived1, public derived2

   如果用到了base中的某个成员变量就不会产生二义性。和#progmaonce在头文件中的作用类似。

#include <iostream>

using namespace std;

 

class Parent

{

public:

      int p;                                          // p将会被所有的子类继承,也将是二义性的根源

      inline Parent()

      {

              p = 10;

      }

};

 

class Child1 : public Parent

{

public:

      int c1;

      inline Child1()

      {

              p =12;                          // p在子类Child1中被赋值为12

              c1 = 12;

      }

};

 

class Child2 : public Parent

{

public:

      int  c2;

      inline Child2()

      {

              p =13;                         // p在子类Child2中被赋值为13

              c2 = 13;

      }

};

 

class GrandChild : public Child1, public Child2

{

public:

      int grandchild;

     // p显然也存在于GrandChild中,但是到底是12,还是13呢?这就产生了二义性

      inline GrandChild()

      {

              grandchild = 14;

      }

 };

 

int main(void)

{

      GrandChild* pGC = new GrandChild();

     

      cout << pGC->p << endl;

 

      return 0;

}

 上面程序是不能通过编译的,derived class中要保持base class的完整原样性原则。

 在上面的示例程序中做如下改动:

class Child1 : public Parent       ->    class Child1 : virtual public Parent

class Child2 : public Parent     ->      class Child2 : virtual public Parent

GrandChild的定义维持不变:

class GrandChild : public Child1, public Child2

 加上了virtual关键字后,就可以保证Parentsuboject在GrandChild中只存在一份。上面修改后的程序运行结果是13,这说明Child2类的那个p起了作用,如果GrandChild的定义写成: class GrandChild : public Child2, public Child1那么运行结果将是12。

  在多重继承的时候,如果父类中有同名的成员变量,为了防止二义性,一般要采用虚继承的方式,并且最右边的基类中的那个成员变量会出现在派生类对象中。

 

【上篇】
【下篇】

抱歉!评论已关闭.