关于虚继承(在钻石继承体系中,一定要用虚继承!)

来源:互联网 发布:手机能不能做淘宝抠图 编辑:程序博客网 时间:2024/04/28 03:13

在钻石继承体系中,一定要用虚继承!

1.下面的代码块儿无法通过编译,原因是,A3无法确定自己到底是用哪一个父类中的函数。

 

class A{public:virtual void f(){}virtual void g(){}};class A1 : virtual public A{public:virtual void f(){}};class A2:  virtual public A{public:virtual void f(){}};class A3 : public A1, public A2{};

 下面这个通过了编译。原因是,A3确定了自己的实现方式。

class A{public:virtual void f(){}virtual void g(){}};class A1 : virtual public A{public:virtual void f(){}};class A2:  virtual public A{public:virtual void f(){}};class A3 : public A1, public A2{public:virtual void f(){}};

 下面的代码中,A3仍然无法确定自己的实现方式。但是可以定义A3的对象。这是因为每一个函数只有一个虚函数表。

class A{public:virtual void f(){}virtual void g(){}};class A1:  public A{};class A2:  public A{};class A3:  public A1, public A2{};

 同理,下面的代码也能通过编译:

class A{public:virtual void f(){}virtual void g(){}};class A1:  public A //不需要虚继承{public:virtual void f(){}};class A2:  public A //不需要虚继承{public:virtual void g(){}};class A3:  public A1, public A2{};

  同理,下面的代码也能通过编译:

class A{ public:virtual void f(){} };class A1: public A{};class A2: public A{};class A3: public A1, public A2{};

 

但是。这三种方式存在一个致命的弱点,就是,如果不用虚继承。下面的代码无法通过编译:

  A3 a3;   A& a = a3;

 用虚继承:则可通过

class A{public:virtual void f(){}virtual void g(){}};class A1:  virtual public A{public:virtual void f(){}};class A2:  virtual public A{public:virtual void g(){}};class A3:  public A1, public A2{};
 A3 a3; A& a = a3;虚继承的含义是,不一定会为孙子类提供实现。为孙子类提供实现的有可能是自己,也有可能是兄弟,也有可能是父类。在钻石继承体系中,一定要用虚继承来避免在钻石体系中的二义性

 

原创粉丝点击