設計模式:單例模式

  • 定義:單例模式(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釋放掉。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章