2013-03-06 32 views
-1

我在我們的軟件中遇到了這樣一段代碼,它依靠析構函數釋放一個鎖。然而,當我運行程序時,析構函數永遠不會被調用,並且鎖定永遠不會被釋放。我們可以依靠析構函數多少?

bool someClass::someFunc() 
{ 
    Locker lock(m_lock); //take lock in constructor, release lock in Locker destructor 
    return something; 
} 

這裏怎麼回事?編譯器可以優化這個函數是否內聯?

class Locker { 
    public: 
     Locker(Lock& lock) : m_lock(lock) { m_lock.lock(); } 
    ~Locker() { m_lock.unlock(); } 
    protected: 
    Lock& m_lock; 
} 
+8

你怎麼知道析構函數從來沒有被調用過?你可以給一個完整的,最小的repro? – SirPentor 2013-03-06 01:58:55

+2

除非你的程序使用特殊的系統調用來退出(例如'_exit()'),這幾乎是不可能的,因爲[C++是RAII之王](http://lazarenko.me/2013/03/03/automatic-資源管理/)。請發佈一個演示問題的最小工作代碼示例。 – 2013-03-06 01:59:16

+3

這是基本的RAII,析構函數會被調用.. – 2013-03-06 01:59:28

回答

2

你確定Locker實際上釋放了析構函數中的鎖嗎?除非程序崩潰或中止或出現其他異常情況,否則您可以指望被調用的析構函數。也許你的調試器顯示錯誤的值?

如果編譯器優化它的內聯,代碼仍然會被執行。 「內聯」並不意味着代碼永遠不會運行。

+0

類鎖櫃 { public: 更衣櫃(鎖定和鎖定):m_lock(鎖定){m_lock.lock(); } 〜Locker(){m_lock.unlock();} } protected: Lock&m_lock; – ddahuja 2013-03-06 02:04:22

+0

你有什麼跡象表明它沒有被解鎖?有時你的調試器顯示不準確的信息 - 你能否在析構函數中輸出一些文本來測試它是否被調用? C++ *應該*調用那個析構函數。 – 2013-03-06 02:07:16

+1

我唯一的疑問是,如果內聯會阻止對象超出範圍,那麼即使內聯析構函數被調用,我也會通過小例子進行驗證。所以更多的業務邏輯調試!謝謝你的答案。 – ddahuja 2013-03-06 02:43:20

2

我懷疑你的意見,析構函數沒有被調用是錯誤的。以下是如何一勞永逸地證明這一點:

#include<iostream> 

class Locker { 
    public: 
     Locker(Lock& lock) : m_lock(lock) { m_lock.lock(); std::cout<<"locked\n"; } 
    ~Locker() { m_lock.unlock(); std::cout<<"unlocked\n"; } 
    protected: 
    Lock& m_lock; 
} 

Ofcourse,這只是爲了滿足自己的析構函數被調用。不要在那裏留下線:)

相關問題