单例模式是一种创建型模式,旨在保证类只创建一个实例。让类自身负责保存它的唯一实例,这个类可以保证没有其他实例被创建,并且它可以提供一个访问该实例的方法,这个类称为单例类,这个唯一实例是单例类的静态成员,静态概念在类中的应用参考:https://blog.youkuaiyun.com/simonyucsdy/article/details/82728456。
单例模式的要点有三个:
- 类只能有一个实例
- 向外部隐藏实例的创建(即实例的创建在自身内部完成)
- 向外部提供访问这个实例的接口
类只能有一个实例,意味着要提供一个自身的静态私有成员变量,独立于任何一个类对象;向外部隐藏实例的创建,则要将单例类的构造函数声明为私有;另外要提供一个公有的静态方法去访问静态成员。
应用实例
实现配置单例类,隐藏构造函数,向外部提供Instance()接口。
//配置单例
class Setting
{
public:
static Setting * Instance();
virtual ~Setting() { delete m_instance; }
void ShowGlobalNum() {
std::cout << "glogal num = " << m_globalNum << std::endl;
}
void SetGlobalNum(int num) {
m_globalNum = num;
}
private:
Setting() : m_globalNum(0) {}
static Setting *m_instance;
int m_globalNum;
};
Setting *Setting::m_instance = NULL;
Setting *Setting::Instance() {
if (NULL == m_instance)
m_instance = new Setting();
return m_instance;
}
测试
int main()
{
Setting::Instance()->SetGlobalNum(10);
Setting::Instance()->ShowGlobalNum();
Setting::Instance()->SetGlobalNum(20);
Setting::Instance()->ShowGlobalNum();
Setting::Instance()->SetGlobalNum(30);
Setting::Instance()->ShowGlobalNum();
Setting::Instance()->SetGlobalNum(40);
Setting::Instance()->ShowGlobalNum();
return 0;
}
运行结果说明测试的过程中操作的始终是同一个实例。
优点
实现了“全局实例”的功能,系统操作的始终是同一个实例,某些特定的应用场景例如配置类,这点很重要。同时也节约了系统开销,例如某个实例需要频繁的创建和销毁,那么使用单例模式可以极大的节约资源。
缺点
首先不符合“开闭原则”,功能的更改必须依靠代码的更改才能实现,且如果单例类的功能过于复杂,则在一定程度上违背了“单一职责”原则。不过同单例模式带来的优点相比,其缺点尚在可忍受的范围。