上下文1:D類:public B1,public B2 {};在初始化列表中使用超類的地址/指針
背景2:B2採用B1初始化:B2(B1 *)// B2的構造
我的問題是,在D的初始化列表:
d :: d():B1(),B2 (?)... 應該在什麼地方?
我不想把 「(B1 *)本」 的?因爲在初始化列表中使用「this」並不好。由於B1部分已經初始化,所以使用它是有意義的。
我該怎麼辦?
上下文1:D類:public B1,public B2 {};在初始化列表中使用超類的地址/指針
背景2:B2採用B1初始化:B2(B1 *)// B2的構造
我的問題是,在D的初始化列表:
d :: d():B1(),B2 (?)... 應該在什麼地方?
我不想把 「(B1 *)本」 的?因爲在初始化列表中使用「this」並不好。由於B1部分已經初始化,所以使用它是有意義的。
我該怎麼辦?
這是確定使用的this
的B1
一部分,因爲它已經被初始化。 §12.6.2/ 5:「直接基類應按聲明順序進行初始化,因爲它們出現在基本說明符列表中(不管mem初始化程序的順序如何)。」
這裏的基地說明符列表是class D : public B1, public B2
,而mem-initializer-list是D::D() : B1(), B2(…)
。
雖然我會說這有「代碼味道」。
編輯:現在我明白您的顧慮,this
是否在構造函數,它不包括成員初始化的體外不確定的。允許這種語言被埋在兩個例子之間,我首先錯過了它。第7段:「mem-initializer的表達式列表中的名稱將在指定了 mem初始化程序的構造函數的作用域中進行評估。」
如果B2
實際上需要保留一個指向B1
的指針,並且該指針始終指向派生最多的對象,請考慮虛擬繼承。
class B1 {};
class B2 : virtual B1 {}; // under the hood, B2 has a pointer to B1.
class D : public virtual B1, public B2 {}; // D has a pointer too
// Only the most-derived class (the one actually used for instantiation)
// implements space for and initialization of the B1.
這是有風險的代碼。正如前面指出的那樣,B1是在B2之前構建的,所以你可以安全地做到這一點,但是如果類定義的改變不再是這種情況,並且它在代碼中不相關的地方,所以你看不到當你打破它時你破壞了代碼。
我會仔細看看這個設計 - 是否有可能改變它使之變得不必要?你能將事物移入成員來封裝而不是繼承 - D真的是B1和B2嗎?
常見的情況是,一個成員依賴另一個成員,如果定義發生變化,開發人員有責任改變實現。 我可以改變我的設計,這很容易,但我想發現這個問題的技術方面,因爲它是有道理的。 – 2010-04-12 07:22:55
@JQ:你說「會員」而不是「基地」。如果他們真的是會員,那麼你就沒有這個問題。他們? – Potatoswatter 2010-04-12 07:30:27
@Patatoswatter:我再次重複以下內容 「我可以改變我的設計,這很容易,但我想發現這個問題的技術方面,因爲它是有意義的」 – 2010-04-13 02:25:49
對我來說,B1和B2不是繼承關係,我不想爲了解決這個問題而改變B2。 – 2010-04-12 07:17:40