智能指针自动识别类型,正确调用析构函数的方法
来源:互联网 发布:网络推广工作基本做法 编辑:程序博客网 时间:2024/06/05 07:09
智能指针大家都知道,里面保存了一个形如 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保存起来了。
大家可以构造一些简单代码验证一下是否正确调用了析构函数。
- 智能指针自动识别类型,正确调用析构函数的方法
- FastReport里面正确调用函数的方法
- warning C4150: 删除指向不完整“CBasexxx”类型的指针;没有调用析构函数
- warning C4150: 删除指向不完整“CClient”类型的指针;没有调用析构函数
- 指针类型的函数
- 调用COM的正确方法
- 正确使用auto_ptr智能指针
- [简记]通过函数指针调用函数的不同方法
- 成员函数指针和其他类型的强制转换,使用一般指针调用成员函数
- 函数指针 的调用
- 函数指针的调用
- 智能指针类型转换
- 智能指针类型转换
- 为什么通过空指针(NULL)可以正确调用一些类的成员函数?
- 为什么通过空指针(NULL)可以正确调用一些类的成员函数?
- 为什么通过空指针(NULL)可以正确调用类的部分成员函数
- 为什么通过空指针(NULL)可以正确调用一些类的成员函数?
- 数据共享+指向自身类型的指针+智能指针
- 整理之c++笔试
- 整理之c++笔试2
- 移位运算符
- 天地游公司游戏开发笔试题
- iPhone UI 设计的一些标准尺寸1
- 智能指针自动识别类型,正确调用析构函数的方法
- c#笔记
- 黑马程序员-JAVA高级(IO输入与输出)PART2
- IOS中各种图片大小尺寸汇总
- 错排用于递推!!!
- KNN分类器
- irc使用
- oracle job 及存储过程案例
- KMP算法初探