- 定義:單例模式(Singleton Pattern):單例模式確保某一個類只有一個實例,而且自行實例化並向整個系統提供這個實例,這個類稱爲單例類,它提供全局訪問的方法。
- 代碼中的三個要點:
- 單例類的構造函數爲私有;
- 提供一個自身的靜態私有成員變量;
- 提供一個公有的靜態工廠方法。
- 下面以單例模式中的懶漢模式(推遲創建對象)爲例,說明單例模式:
//Singleton1.h
#ifndef __SINGLETON_H__
#define __SINGLETON_H__
#include<string>
class Planet {
private:
Planet(const std::string& name);
std::string m_name;
static Planet* s_pPlanet;//static member must init out of class;except for static const member.
public:
virtual ~Planet();
static Planet* GetInstance(const std::string& name);
std::string Getname();
};
#endif
//Singleton.cpp
#include<cstdio>
#include "Singleton1.h"
Planet* Planet::s_pPlanet = nullptr;
Planet::Planet(const std::string& name) : m_name(name) {}
Planet ::~Planet() {}
Planet* Planet::GetInstance(const std::string& name)
{
if (s_pPlanet == nullptr)
{
s_pPlanet = new Planet(name);
}
return s_pPlanet;
}
std::string Planet::Getname()
{
return m_name;
}
int main()
{
Planet* pPlanet = Planet::GetInstance("Earth");
printf("%s \n", pPlanet->Getname().c_str());
system("pause");
return 0;
}
- 分析:
- 該模式下,由於構造函數是private的,所以不能通過聲明對象的方式進行構造函數調用。但可以通過GetInstance函數進行對象構造。
- 該方式通過GetIstance函數創建(new)了對象,但沒有對其進行釋放,雖然在程序結束後操作系統可以釋放它。但不能主動釋放對象的程序仍是不健全的。因此有下面的改進。
//Singleton2.h
#ifndef __SINGLETON__H__
#define __SINGLETON_H__
#include<string>
class Planet
{
public:
virtual ~Planet();
static Planet* GetInstance(const std::string& name);
std::string Getname();
private:
Planet(const std::string& name);
std::string m_name;
static Planet* s_pPlanet;
class CGarbo
{
~CGarbo()
{
if (Planet::s_pPlanet != NULL)
{
delete s_pPlanet;
}
}
};
static CGarbo s_Cgarbo;
};
#endif
- 分析:
- 爲了解決不能主動釋放對象的問題,該方法在在類中添加了一個靜態成員s_Cgarbo,該成員類型爲類,只提供析構函數(構造函數使用默認構造),析構函數的功能就是釋放掉Singleton類對象。由於類靜態成員的生命週期爲程序結束,所以當程序結束時析構CGarbo對象,調用~CGarbo()函數時會一同將s_pPlanet釋放掉。