2012-08-02 48 views
2

假設我有類A,B和C通過構造函數初始化集初始化的變量的銷燬順序是什麼?

如果我然後有容器如下

Container::Container() 
:A(10),B(20),C(30) 
{ 
    //Do something specific 
} 

現在,如果我調用容器的析構函數,即〜集裝箱() 我注意到,析構函數越來越按照相反的順序調用 即〜C(),〜B()然後〜A()

這是什麼東西總是固定的順序? 任何人都可以拋出一些建設初始化集的析構函數的更多的燈光?

回答

7

訂單是固定的,但不是初始化列表。

這是成員在類中聲明的相反順序。

class Container 
{ 
    A a; 
    B b; 
    C c; 
}; 

Container對象被銷燬,其中,所述部件被破壞的順序是cba

如果您按照與聲明不同的順序初始化成員,則某些編譯器會發出警告,並且保持一致性很好。

+0

是的,我現在明白了。所以,如果我混淆了聲明/或初始化順序的順序,銷燬順序可能會變得混亂。保持聲明和初始化之間的一致性是有意義的。我知道這個規則,但不知道它也適用於構造初始化集。 – rajshenoy 2012-08-02 06:59:42

+0

@rajshenoy好吧,破壞的順序會改變,但它不會搞砸。它仍然是明確的。 :) – 2012-08-02 07:03:08

+0

@rajshenoy但是,如果你在我的例子中交換b和c,那麼b首先會被銷燬。 – 2012-08-02 07:03:37

6

它們總是以相反的順序銷燬。無論初始化程序列表中的順序如何,構造順序始終是聲明的順序。

3

成員(和非虛擬子對象)按其聲明的順序構建,並按相反順序銷燬。初始值設定項列表中的初始值設定項的順序無關,但強烈建議保持相同,以保持自己和身邊的每個人都清醒。

想象一下,你有這樣的:Foo(int n) : a(n), b(a) { }。這看起來不錯,但如果在Foo::a之前實際聲明Foo::b,則這可能是未定義的行爲(如果b的構造函數需要完整類型)。爲了防止這種情況,您應該始終啓用並遵守相關的編譯器警告。

+2

這是否是UB取決於'b'的細節。如果'B :: B'只需要存儲一個'A&',它就是明確的。一個類似的情況是將'* this'傳遞給成員對象,以便它知道它的父對象。這在構建之前也「提及」了一個對象。 – MSalters 2012-08-02 06:57:14

+0

@ MSalters:謝謝,好點!編輯。 – 2012-08-02 06:58:27

相關問題