由于C++沒(méi)有垃圾回收機(jī)制, 所以使用普通指針來(lái)實(shí)現(xiàn)Singleton模式, 會(huì)存在程序結(jié)束后釋放資源的隱患, 系統(tǒng)只會(huì)回收指針?biāo)赶虻膬?nèi)存, 而不會(huì)回收網(wǎng)絡(luò)連接, 數(shù)據(jù)庫(kù)連接等持有的資源, 這些資源必須程序員自己去顯示的釋放. 所以使用std::auto_ptr可以很好的解決這一問(wèn)題. 也可以使用靜態(tài)的對(duì)象來(lái)實(shí)現(xiàn)Singleton, 但是這段時(shí)間卻在一工程中遇到一問(wèn)題, 有一Singleton的類如果是用靜態(tài)對(duì)象實(shí)現(xiàn)的, 在Mac下可以很好的運(yùn)行, 但是在Windows上卻讓程序異外退出. 但是如這個(gè)Singleton類使用普通指針來(lái)實(shí)現(xiàn), 在Mac上與Windows里都能很好的工作. 把此類單獨(dú)出來(lái)在一很干凈的工程中使用, 卻在兩平臺(tái)下都能正常運(yùn)行, 怪哉. 即使把工程的重新清空N次, 再編譯, 靜態(tài)對(duì)象的Singleton問(wèn)題依舊存在, 不解. 同樣功能的東西, 換個(gè)類名, 卻又正常了, 此類不正常工作時(shí)名為ConfigUtil, 換成Configs卻可以了. 但工程中此類名卻是唯一的, 不知何故, 跟此名字干上了, 哎.
使用std::auto_ptr需要的頭文件: #include <memory>
auto_ptr是一個(gè)類模板, auto_ptr的構(gòu)造:
std::auto_ptr<pointed_type> ap; 此時(shí)get()返回0.
std::auto_ptr<pointed_type> ap(new pointed_type());
std::auto_ptr<pointed_type> ap(auto_ptr_with_the_same_type);
std::auto_ptr<pointed_type>::get(): 返回auto_ptr對(duì)象底層指向的內(nèi)存地址, 就是new pointed_type這個(gè)指針的內(nèi)存地址.
std::auto_ptr<pointed_type>::release(): 返回auto_ptr對(duì)象底層指向的內(nèi)存地址, 并且釋放此auto_ptr對(duì)象對(duì)此內(nèi)存地址的所有權(quán), 即此auto_ptr對(duì)象作用局結(jié)束后, 并不會(huì)再去釋放此內(nèi)存地址. 這種方式可以使兩auto_ptr對(duì)象指向同一內(nèi)存地址, 卻只有一個(gè)對(duì)其有所有權(quán). 如果多個(gè)auto_ptr對(duì)同一內(nèi)存地址都有所有權(quán), 那么他們作用局結(jié)束的時(shí)候, 此內(nèi)存地址會(huì)被釋放多次, 這是很危險(xiǎn)的. 要避免多個(gè)auto_ptr對(duì)象擁有同一內(nèi)存地址.
std::auto_ptr<pointed_type>::reset(new pointed_type()): 重新設(shè)置auto_ptr指向的對(duì)象, 并且釋放已經(jīng)指向的內(nèi)存(調(diào)用delete).
#include <iostream>
#include <memory>
class Singleton {
public:
static Singleton& getInstance() {
if (auto_ptr_instance.get() == 0) {
auto_ptr_instance.reset(new Singleton());
}
return *(auto_ptr_instance.get());
}
void print() {
std::cout << "void print()" << std::endl;
}
private:
Singleton() {
std::cout << "Singleton()" << std::endl;
}
~Singleton() {
std::cout << "~Singleton()" << std::endl;
}
Singleton(const Singleton &other);
Singleton& operator=(const Singleton &other);
friend class std::auto_ptr<Singleton>;
static std::auto_ptr<Singleton> auto_ptr_instance;
};
std::auto_ptr<Singleton> Singleton::auto_ptr_instance;
int main(int argc, char *argv[]) {
Singleton::getInstance().print();
return EXIT_SUCCESS;
}