虛擬繼承的意義 (轉)

worldblog發表於2007-12-15
虛擬繼承的意義 (轉)[@more@]

在類過載中我們一般使用以下的方式:

class Base
{
  void Echo() { printf("Echo from Base");}
};

class Middle : public Base {}

class Child : public Middle {}

可以很清楚的看出過載過程是 Base->Middle->Child.
這樣的結構使用預設的過載方式就可以了.

void main()
{
  Child c;
  c.Echo(); // 正確.
}

但是在某些時候,我們需要從基類分出若干子類,然後再由子類進行多重繼承,
這個時候以上的方法就會出錯.

比如:

class Base
{
  void Echo() { printf("Echo from Base");}
};

class Middle1 : public Base {}
class Middle2 : public Base {}

class Child : public Middle1,Middle2 {}

void main()
{
  Child c;
  c.Echo(); // 錯誤.不明確.
}

這是因為編譯時認為Middle1和Middle2是兩個類體系
來自不同的Base類(雖然兩個Base宣告一模一樣),所以在呼叫
Base類的Echo時無法確認指向那一個.

解決的方法是使用"虛擬繼承".

如下所示:

class Base
{
  void Echo() { printf("Echo from Base");}
};

class Middle1 : virtual public Base {}
class Middle2 : virtual public Base {}

class Child : public Middle1,Middle2 {}

void main()
{
  Child c;
  c.Echo(); // 正確.函式呼叫來自同一基類.
}

以下圖示更能描述預設繼承和虛擬繼承的區別.

預設繼承:

  base base
  |   |
  |    |
  Mid1 Mid2
  |   |
    |
  Child

存在兩個類體系是出錯的原因.

虛擬繼承:

   base
   |
  |   |
  Mid1 Mid2
  |  |
    |
    Child

使用虛擬繼承將類的體系整合起來.


一點學習的,不足之處請指出.


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752043/viewspace-993695/,如需轉載,請註明出處,否則將追究法律責任。

相關文章