Singleton模式是常用的设计模式之一,它保证类只有一个对象实例, 并提供一个访问它的全局访问点。
1>方式1
class Singleton
{public:
static Singleton * Instance()
{
if( 0== _instance)
{
_instance = new Singleton;
}
return _instance;
}
protected:
Singleton(void)
{
}
virtual ~Singleton(void)
{
}
static Singleton* _instance;
};
Singleton* Singleton::_instance = NULL;
这是教科书上使用的方法。看起来没有什么问题,其实包含很多的问题。如内存释放,调用形式如 Singleton*p = Singleton::Instance();,然后程序用完这个实例p指针后,要在程序结束前调用delete p;来释放内存。即使我们这么做了,代码还是有问题。因为delete p;会导致编译不过的(因为析构函数保护类型,无法调用)。
下面我们一个一个的解决。
2> 方式2
其实可以用如下简单方式来实现一个可用的singleton:
class Singleton
{
public:
static Singleton& GetInstance() ---这里的函数限定词static就是声明此函数为静态成员函数,外部可以直接访问此函数
{
static Singleton instance;
return instance;
}
private:
//类只能有一个实例,且只能通过GetInstance拿到对象实例,所以防止通过构造、拷贝或者赋值得到对象实例。
Singleton( ) { };
Singleton(const Singleton& p);
Singleton& operator=(Singleton& p);
public:
void DoSomething() {cout << "My test" << endl; };
};
int _tmain(int argc, _TCHAR* argv[])
{
Singleton::GetInstance().DoSomething(); //Correct
Singleton singleton = Singleton::GetInstance(); //编译出错(不能访问private拷贝构造函数),
//这样就可以阻止拷贝生成多个Singleton实例,
//实现只有唯一一个Singleton的实例(static Singleton instance;)
Singleton& singleton = Singleton::GetInstance(); //Correct, 这里通过引用的方式得到的,
//其实还是static Singleton instance
singleton.DoSomething();}
}
上面的1>方式1程序必须记住在程序结束的时候,释放内存。为了让它自动的释放内存,我们引入auto_ptr改变它。
#include <memory>
#include <iostream>
using namespace std;
class Singleton
{
public:
static Singleton * Instance()
{
if( 0== _instance.get())
{
_instance.reset( new Singleton);
}
return _instance.get();
}
protected:
Singleton(void)
{
cout <<"Create Singleton"<<endl;
}
virtual ~Singleton(void)
{
cout << "Destroy Singleton"<<endl;
}
friend class auto_ptr<Singleton>;//这里声明class auto_ptr<Singleton>为类Singleton的友元类就是为了在class auto_ptr<Singleton>类里能调用类Singleton的保护类型的析构函数
static auto_ptr<Singleton> _instance;
};
//Singleton.cpp
auto_ptr<Singleton> Singleton::_instance;