由于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;
}