說我們有經典的多重繼承模式:爲什麼不用只有一個虛擬繼承的鑽石繼承?
class Base {
int baseMember;
};
class A : public Base {
int aMember;
};
class B : public Base {
int member;
};
class Derived : public A, public B {
int derivedMember;
};
這將奠定了在內存中派生的對象是這樣的:
- 基地的領域< - (基地*)(A *)這個| (A *)this |
- A的字段
- Base的字段< - (Base *)(B *)this | (B *)這
- B的字段
- Derived的字段
爲了防止基礎的字段被複制,則缺省的方法是inherite幾乎從鹼和B:
class A : public virtual Base {
...
class B : public virtual Base {
這會導致以下佈局:
- 抵消基地的字段< - (A *)this |這
- A的領域
- 偏移到基地的領域< - (B *)這個
- B的領域
- Derived的領域
- 基地的領域< - (基地*)這個| (Base *)(A *)this | (Base *)(B *)
解決了這個問題,您必須權衡應用偏移量從其他類訪問Base字段(和虛函數)的問題。
但爲什麼以下不可能?
- Base's fields < - (Base *)(B *)this | (Base *)(A *)this | (A *)this |這
- A的領域
- 偏移到基地的領域< - (B *)這個
- B的領域
- Derived的領域
這將使A和衍生無開銷訪問基地,沒有重複,甚至將大小縮小1個整數。但是,如果我嘗試它,編譯器仍然複製Base的字段(將它們放在B的字段後面)。
note:我知道有類似的問題已經被問到,但我還沒有看到爲什麼這是不可能的。
在您看到Derived之前,您需要佈置A和B.一旦你選擇了佈局,它就是一成不變的。派生和所有其他類必須使用它的A和B子對象。 –