2017-10-18 141 views
1

可以說我有以下幾點:成員函數何時超出範圍?

struct Foo 
{ 
    Foo() : bar([&]{ doSomething();}) 
    std::function<void(void)> bar; 
    void doSomething(){}; 
} 

而且可以說,一個線程調用經常一個Foo實例的杆件,而另一個線程自毀foo的實例。因爲Foo的析構函數被首先調用,所以調用bar會導致無效的函數調用嗎?在釋放之前,Foo的析構函數是否使無效的成員函數調用?

編輯: 對不起,我應該有一個更具體一點,調用doSomething成爲未定義之前bar的析構函數被調用?

+0

成員變量存在於對象中。如果沒有對象,那麼成員變量如何存在? –

+2

這是你的責任,以確保沒有線程破壞一個對象,而另一個線程是或可能正在使用它。 –

+0

這就是爲什麼一個對象無法同步其自身的破壞的主要原因。如果你想實現'銷燬請求',也就是說,一個對象可以被請求在同時處理其他請求的同時被破壞,這必須在*外部*,而不是由類本身同步。 – ComicSansMS

回答

0

成員函數保持有效,直到對象有效。當對象被銷燬時,成員函數也被銷燬,並且當調用析構函數時對象被銷燬。因此,析構函數中的調用使成員函數失效。而且如果在對象銷燬後調用成員函數會導致未定義的行爲。所以,你需要確保在對象被銷燬後沒有成員函數被調用。

3

由於Foo的析構函數被首先調用,調用bar會導致無效的函數調用嗎?

是的,除非你確定沒有發生。

Foo的析構函數在釋放之前調用invalidate成員函數嗎?

是的。只要析構函數被調用,對該對象及其子對象的所有引用就會失效。

請注意,成員函數與您有什麼不同。你有什麼是一個成員對象的函數包裝器。雖然這個區別對答案沒有任何影響。

+0

澄清:*無效*這意味着它在析構函數啓動後立即執行成員函數不再有效。該語言實際上並沒有強制執行此操作。確保這絕不會發生的是你的責任。如果你沒有正確地做到這一點,該程序可以炸燬你的臉。 – ComicSansMS