关于单例类模板析构的问题

		关于单例类模板析构的问题
   单例类是大家所熟悉的,在程序里面只需要一个实例,并且生命周期和程序一样长,就可以用单例模式。但是单例模式销毁是个问题,因为在关闭程序的时候,程序不会自动调用单例类的析构函数的。
   解决办法:
   在单例模板类里面添加一个内嵌类(本文这里叫CGarbo)专门是为了析构单例类而建立的类。利用这个内嵌类声明一个静态成员变量sGarbo.因为在c++里面静态成员函数会被自动析构的,在这个成员的析构函数中,来析构单例类,看看这个CGarbo的析构函数。其实有很多文章介绍了该方法的,但都是直接基于单例类,而不是单例模板类,所以在定义sGarbo这个静态成员变量的时候,出了些问题,下面是我最开始定义的代码,但是不同通过vs的编译,
   template< class T >  PlantSingleton::CGarbo PlantSingleton::sGarbo;
   上网搜索了半天,原来是在模板PlantSingleton前面加上typename,来告诉编译器这是个内嵌类,编译器就可以通过编译了,代码就编程这样:
   template< class T > typename PlantSingleton::CGarbo PlantSingleton::sGarbo;
   但是,问题又来了,这仅仅是对成员变量sGarbo的声明,而不是定义,也就是说sGarbo一直未生成,当然也就没有析构了,那么单例类也就不会被析构了。没办法,在方法GetInstance中加上sGarbo,这是无用的代码,而且很丑陋,可是为了析构,就先试着用用,别说还真管用,所有的单例类在关闭程序后真的可以析构了。正在我高兴的时候,又出现问题了,程序崩溃了。崩溃的原因是在析构的过程中,遇到一个静态变量,已经被析构了,但是还调用了它。因为我们这个方法的原理是利用程序退出时会自动析构静态变量的,但是我们不能确定究竟先析构那个静态变量,所以程序崩溃也是理所当然的了。
   看来我需要转换思路了,其实这种单例类一般不析构也不会出现大问题,因为他们不是动态不断增加的,但是为了检测到程序里面究竟有没有内存泄露,必须把这些单例类产生的内存分配的情况必须排除掉,那我就设置一个按钮,手动关闭程序,并且在关闭程序之前手动析构所有的单例类,就可以了。
   下面是为了自动调用析构函数的源码,看来不是个好方法。昨天读了《道法自然》,里面说了另外一种析构的方法,就是增加静态的析构函数,我没试,不知道好不好用
 
  
 
  
#ifndef __SINGLETN_H__
#define __SINGLETN_H__

#include "cocos2d.h"

template< class T >
class Singleton
{
public:
	class CGarbo //它的唯一工作就是在析构函数中删除CSingleton的实例
	{
	public:

		~CGarbo()
		{
			if(  PlantSingleton::spInstance )
			{
				delete  PlantSingleton::spInstance;
				PlantSingleton::spInstance = NULL;
			}
		}
	};
	

private:
public:
	static T* spInstance;

public:

	~Singleton( )
	{

	}

	static T* GetInstance( )
	{
 		if ( spInstance == 0 )
 			spInstance = new T;
		return spInstance;
		
	}	
protected:
	//定义一个静态成员,程序结束时,系统会自动调用它的析构函数
	static CGarbo sGarbo;	
};
template< class T > typename Singleton::CGarbo PlantSingleton::sGarbo;
template< class T > T* Singleton::spInstance = 0;
#endif // ___SINGLETN_H__

结论,单例类一直占用内存是正常的,它并没有造成内存泄露,但是为了检查其它地方的内存泄露,可以在单例类里面建立一个destroy();方法,此方法里面析构申请的内存,在退出程序之前主动调用destroy();方法,这样就可以检查内存泄露了



你可能感兴趣的:(c++)