由于C++沒有垃圾回收機制, 所以使用普通指針來實現Singleton模式, 會存在程序結束后釋放資源的隱患, 系統只會回收指針所指向的內存, 而不會回收網絡連接, 數據庫連接等持有的資源, 這些資源必須程序員自己去顯示的釋放. 所以使用std::auto_ptr可以很好的解決這一問題. 也可以使用靜態的對象來實現Singleton, 但是這段時間卻在一工程中遇到一問題, 有一Singleton的類如果是用靜態對象實現的, 在Mac下可以很好的運行, 但是在Windows上卻讓程序異外退出. 但是如這個Singleton類使用普通指針來實現, 在Mac上與Windows里都能很好的工作. 把此類單獨出來在一很干凈的工程中使用, 卻在兩平臺下都能正常運行, 怪哉. 即使把工程的重新清空N次, 再編譯, 靜態對象的Singleton問題依舊存在, 不解. 同樣功能的東西, 換個類名, 卻又正常了, 此類不正常工作時名為ConfigUtil, 換成Configs卻可以了. 但工程中此類名卻是唯一的, 不知何故, 跟此名字干上了, 哎.
使用std::auto_ptr需要的頭文件: #include <memory>
auto_ptr是一個類模板, auto_ptr的構造:
std::auto_ptr<pointed_type> ap; 此時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對象底層指向的內存地址, 就是new pointed_type這個指針的內存地址.
std::auto_ptr<pointed_type>::release(): 返回auto_ptr對象底層指向的內存地址, 并且釋放此auto_ptr對象對此內存地址的所有權, 即此auto_ptr對象作用局結束后, 并不會再去釋放此內存地址. 這種方式可以使兩auto_ptr對象指向同一內存地址, 卻只有一個對其有所有權. 如果多個auto_ptr對同一內存地址都有所有權, 那么他們作用局結束的時候, 此內存地址會被釋放多次, 這是很危險的. 要避免多個auto_ptr對象擁有同一內存地址.
std::auto_ptr<pointed_type>::reset(new pointed_type()): 重新設置auto_ptr指向的對象, 并且釋放已經指向的內存(調用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;
}