靜態庫中應慎用靜態類成員

有各種各樣的原因會用到類靜態成員,一般是共享數據,但編寫靜態庫的時候應慎重考慮,因爲用在應用程序中沒什麼問題,但用在DLL中,可能災難就開始了,看以下一個例子:

靜態庫中有一個名爲TestSQL的數據庫操作類,有一個靜態成員m_count記錄對某一數據庫的訪問記數,每有一次數據庫操作就將該值加一。當然在靜態庫裏會把這個值初始化爲0:
int TestSQL::m_count = 0;
爲了應付多線程操作的情況,該類內部很好地實現了同步處理機制。這樣編程很方便,只要連接這個靜態庫,不管產生了多少TestSQL的對象,都能知道對數據庫的操作次數。數據庫操作很複雜,會執行一些存儲過程,而且數據庫存儲過程可能會變,那相應調用代碼也要變動,自然會想到把這些代碼放到一個DLL,數據庫存儲過程變動,只要修改這個DLL的代碼就行了。應用程序執行簡單的數據庫操作,當要執行存儲過程就調用這個DLL。好,問題來了,應用程序執行了一個數據庫查詢操作,然後調用DLL執行一個存儲過程,這時候這個靜態m_count的值是多少?是2嗎?錯了,應用程序裏是1,DLL裏面也是1,即使是把EXE裏的TestSQL對象作爲參數傳給DLL執行,也還是1,因爲雖然是在同一個進程空間,但是編譯器編譯的時候,是把靜態庫連接進來,EXE和DLL分別有自己的int TestSQL::m_count,因此EXE和DLL是分別記數的,即使把EXE裏產生的對象:TestSQL* sqlExe作爲參數傳遞給DLL,但是在DLL裏面執行sqlExe->數據庫操作函數(),是在自己的m_count上記數,並不會改變EXE裏的m_count值。

上面講的這種情況還不會產生異常,如果靜態成員是指針的話,就有可能會引起非法操作了,因此編寫靜態庫的時候,應注意這個問題。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章