单例模式的设计分析(自动释放实例内存)

-----Edit by ZhuSenlin HDU

方法一:利用私有静态成员变量static Singleton m_Instance实现

1) 因为只有一个实例,所以我们不能把构造函数借口暴露给用户(否则用户可以创建很多个)。所以采用一个静态成员函数static Singleton* GetInstance();来获取实例。

2) 因为只有一个实例,我们不想让用户随便删除,所以我们需要把析构函数设为私有。(其实直接delete也会出错,因为实例是在栈上分配的),为了使用户能方便的查找代码的疏漏,我们将析构函数设为私有,这样如果用户调用delete,会在编译期间报错,直接将其扼杀在摇篮里。

#include <iostream>
using namespace std;


//单例类

class Singleton
{
private:
	static Singleton m_Instance;
	int* ptest;

	Singleton();
	~Singleton();


public:	
	static Singleton* GetInstance();
	void test();
};

Singleton Singleton::m_Instance;

Singleton::Singleton()
{
	ptest = new int[10];
}

Singleton::~Singleton()
{
	delete [] ptest;
	ptest = NULL;
}

Singleton* Singleton::GetInstance()
{
	return &m_Instance;
}

void Singleton::test()
{
	cout << this << endl;
}

//测试代码

int main()
{
	Singleton* pSingleton1 = Singleton::GetInstance();
	pSingleton1->test();
	Singleton* pSingleton2 = Singleton::GetInstance();
	pSingleton2->test();
	return 0;
}


方法二:利用单例抓取器来获取单例,每创建一个某个单例的抓取器,这个单例的引用计数加1,销毁一个某个单例的抓取器,该单例的引用计数就减1。当引用计数变为0时则销毁这个单例。如果再次创建该单例的抓取器,这个单例也有被重新实例化。

#include <iostream>
using namespace std;


//单例类

class Singleton
{
friend class SingletonGrabber;
private:
	Singleton(){};
	~Singleton(){};

public:
	void test()
	{
		cout << this << endl;
	}
};

//单例抓取器类

class SingletonGrabber
{
private:
	static Singleton* m_pInstance;
	static unsigned int m_nReference;

public:
	SingletonGrabber();
	~SingletonGrabber();

	Singleton* GetInstance();
};

Singleton* SingletonGrabber::m_pInstance = NULL;
unsigned int SingletonGrabber::m_nReference = 0;

SingletonGrabber::SingletonGrabber()
{
	if(m_pInstance == NULL)
		m_pInstance = new Singleton();

	m_nReference++;
}

SingletonGrabber::~SingletonGrabber()
{
	m_nReference--;
	if(m_nReference == 0)
	{
		delete m_pInstance;
		m_pInstance = NULL;
	}
}

Singleton* SingletonGrabber::GetInstance()
{
	return m_pInstance;
}

//测试代码

int main()
{
	SingletonGrabber grab;
	Singleton* pSingleton1 = grab.GetInstance();
	pSingleton1->test();
	Singleton* pSingleton2 = grab.GetInstance();
	pSingleton2->test();
	return 0;
}


当然,这个抓取器可以应用到任何一个单例中,所以我们可以将其模板化。

#include <iostream>
using namespace std;


//单例类

class Singleton
{
	template <class T>
	friend class SingletonGrabber;

private:
	Singleton(){};
	~Singleton(){};

public:
	void Test()
	{
		cout << this << endl;
	}
};

//抓取器模板类

template <class T>
class SingletonGrabber
{
private:
	static T* m_pInstance;
	static unsigned int m_nRefernce;

public:
	SingletonGrabber();
	~SingletonGrabber();

	T* GetInstance();
};

template <class T>
T* SingletonGrabber<T>::m_pInstance = NULL;

template <class T>
unsigned int SingletonGrabber<T>::m_nRefernce = 0;

template <class T>T* SingletonGrabber<T>::GetInstance(){return m_pInstance;}

template <class T>
SingletonGrabber<T>::SingletonGrabber()
{
	if(m_pInstance == NULL)
		m_pInstance = new T();

	m_nRefernce++;
}

template <class T>
SingletonGrabber<T>::~SingletonGrabber()
{
	m_nRefernce--;
	if(m_nRefernce == 0)
	{
		delete m_pInstance;
		m_pInstance = NULL;
	}
}

//测试代码

int main()
{
	SingletonGrabber<Singleton> grab;
	Singleton* pSingleton1 = grab.GetInstance();
	pSingleton1->Test();
	Singleton* pSingleton2 = grab.GetInstance();
	pSingleton2->Test();
	return 0;
}

 

以上代码均经过测试,无内存泄露问题。

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值