談談C 中的單例

2022-09-25 06:54:07 字數 1389 閱讀 8596

寫c++的時候用到單例,於是很自然的寫出如下的**:

namespace tlanyan

// other members

public:

static foo* getinstance()

return _instance;

}~foo()

// other members and codes

};foo* foo::_instance = null;

}**的本意:靜態成員函式getinstance獲取單例指標,並且在析構函式中做一些收尾工作。

執行**後發現析構函式死活不執行,難道乙個單例模式都能寫錯?反覆確認,沒發現問題所在,於是上萬能的stackoverflow上找原因。正好有夥計有同樣的疑惑,有哥們給出了乙個可行的方案。根據其答案修改**如下:

namespace tlanyan

// other members

public:

static foo& getinstance()

~foo()

// other members and codes};}

對比前一段**,主要改動是移除了靜態指標laqudt成員,改用函式內的靜態成員。由於_instance是函式內的靜態成員,在首次呼叫時被初始化(感謝無參建構函式),之後呼叫將略過初始化而執行後續**;函式返回例項的引用,故而每次呼叫得到的是同乙個物件,達到了單例的目的;程式執行結束後,例項的析構函式被自動呼叫,析構函式中的**正確執行。

問題解決了,但什麼原因造成第一段單例**的析構函式不執行www.cppcns.com呢?

這是由於c++持有物件的方式造成的(或者說c++允許程式設計師手動控制記憶體引起)。j**a/php等帶有**機制的語言,持有物件的方式是通過指標,程式設計師申請物件後會自動分配記憶體,系統負責跟蹤和**無用的物件和存在。c++允許開發人員以變數的方式持有物件,例如:foo foo [= foo(args)]。變數初始化後獲得物件的引用,離開作用域後,系統銷毀執行棧,物件自動被析構。c++也可以以指標的形式獲得物件的引用:foo* foo = new foo(args)。這種方式分配的物件,需要開發人員手動管理。如果不執行delete,物件和分配的記憶體將一直存在,直到程式退出後,才由作業系統**。如下**可說明這點:

namespace tlanyan

}從上面的**可以看出,物件沒有引用計數的情況下,編譯器和系統不敢隨便**new出來的物件記憶體:多個指標指向同乙個物件,delete了物件可能會導致其他**崩潰;釋放記憶體後,其他指標再delete會多次de程式設計客棧lete同一塊記憶體,引發不可預知風險。

綜上,指標單例析構函式沒有被呼叫的原因是: 自己new的物件,需要自己delete,別指望別人幫你正確呼叫析構函式。

問題的解決方案有以下幾種:

程式設計客棧

如有其它解決方案,歡迎交流指正!

談談 單例模式

單例模式是最簡單的一種設計模式,保證 個類僅有 個例項,並提供 個該例項的全域性訪問點。class singleton private singleton 構造 singleton const singleton 拷貝構造 singleton operator const singleton sta...

談談單例模式(一)

單例模式是一種很簡單,很常見的模式。我們創造並使用單例,一般是基於兩點考慮。1.全域性唯一。2.便利的訪問 更多的人的會考慮這個 那麼如何寫出乙個單例模式,寫乙個單例模式我們要思考那些東西,避免那些問題。下面是乙個c 實現的單利模式,不過只考慮了保證全域性只有乙個物件的問題。class single...

C 中的單例模式

c 中的單例模式 靜態成員經典應用 單例模式 在程式執行過程中,可能會希望某些類的例項物件永遠只有乙個 條件1.把建構函式私有化 2.定義乙個私有的靜態成員變數指標,用於指向單例物件 3.提供乙個公共的返回單例物件的靜態成員函式.class rocket return ms rocket stati...