首页 > 其他 > 详细

智能指针自动识别类型,正确调用析构函数的方法

时间:2014-02-11 19:52:09      阅读:538      评论:0      收藏:0      [点我收藏+]

智能指针大家都知道,里面保存了一个形如 T* m_Pointer的指针,当引用计数为零时自动删除m_Pointer,

当T不为void时大家都会写,但是当T为void时,编译器在编译到delete m_Pointer时必定会报错。怎么办呢?我也是苦思冥想好久才用奇技淫巧解决之。而且不光解决void的删除问题,所有类型都可以用这种方法统一解决。解决的关键在成员函数指针。


delete是运算符没办法转化成成员函数,所以声明一个类用来封装之,为了之后统一处理的方便这个类会继承自一个叫VoidClass的类,代码如下:

class VoidClass
{
public:
	VoidClass()
	{
		m_Pointer=0;
	}
	VoidClass(void* p)
	{
		m_Pointer=p;
	}
	void* GetPointer(){return m_Pointer;}
	bool  IsNull(){return m_Pointer==0?1:0;}
private:
	void* m_Pointer;
};

template<typename T>
class Destructor:public VoidClass
{
public:
	Destructor(T* p):VoidClass(p)
	{
	}
	void Do()
	{
		delete ((T*)GetPointer());
	}
};

方便保存成员函数指针,用两个typedef将成员函数类型定义出来:

typedef void(Destructor<T1>::*RawDestructFunc)();
typedef void(VoidClass::*DestructFunc)();

下面的思路就是:

1,把任何指针封装进Destructor,并把Destructor转化为VoidClass保存。

2,把该指针封装进Destructor之后的Do函数(即实际的析构函数)转化成DestructFunc类型保存起来,delete时只用利用VoidClass对象调用DestructFunc即可。

有人说Do函数并没有出现在VoidClass里,为什么能把它转化成VoidClass的成员函数指针。这里不深究这个,我估计编译器只会认地址,只要指针的值不变,成员函数指针的地址值不变,任它类型怎么变都能正常调用。

在智能指针类里加上如下两个成员变量:

VoidClass*     m_Destructor;
DestructFunc   m_DestructFunc;

奇技淫巧来啦,RawDestructFunc转换到DestructFunc的时候用到了一种在MFC里出现过的方法,用union来转换类型,我称之为All_Cast,代码如下:

template<class InputType,class OutPutType>
union cast_union
{
	InputType in;
	OutPutType out;
};
template <class InputType, class OutPutType>
OutPutType All_cast(InputType a)
{
	cast_union<InputType,OutPutType> u;
	u.in=a;
	return u.out;
}

构造函数如下:

	template<typename T1>
	amyKeeper(T1* p)
	{
		typedef void(Destructor<T1>::*RawDestructFunc)();
		Destructor<T1>* dtor=new Destructor<T1>(p);
		m_Destructor=(VoidClass*)(dtor);
		m_DestructFunc=All_cast<RawDestructFunc,DestructFunc>(&Destructor<T1>::Do);
		m_Counter=new Counter;  
		IncKeeper(); 
	}

析构函数如下:

	(m_Destructor->*m_DestructFunc)();
        delete m_Destructor;
        m_Destructor=0;

这样就算调用的时候 mySmartPointer<A> p=new B;或者mySmartPointer<void> p=new B;无论怎么样析构的时候都会正确调用B的析构函数。

因为构造函数自动识别了B的类型:

Destructor<T1>* dtor=new Destructor<T1>(p);

无论mySmartPointer类的模板是什么,构造函数的模板参数永远是B,所以B类的析构函数被正确转化成m_DestructFunc保存起来了。


大家可以构造一些简单代码验证一下是否正确调用了析构函数。





智能指针自动识别类型,正确调用析构函数的方法

原文:http://blog.csdn.net/a63140180/article/details/19073499

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!