判断对象在堆上的代码例子

本文参考了 http://www.tarma.com/articles/1997jan.htm,分享给大家,记得注明出处

#pragma once
#include "./include/vld.h"
//#include"iostream"
#include"cstddef"
#include"list"
#include <map>
#include<algorithm>
#include "atlstr.h"
template<class CHILD_TYPE>
class HeapTracked{
private:
 static std::map<const int,const void *> pointerMap;//存放各个堆对象的指针

 const int ObjSize;
protected:

 //限定了构造函数的当前对象只能为当前子类的对象,而这个函数只能由
 HeapTracked(CHILD_TYPE *pDerivedObj);
 HeapTracked(const HeapTracked<CHILD_TYPE> &);
public:
 class MissingAddress{};//异常类
 virtual ~HeapTracked()=0;//纯虚函数
 static void*operator new(std::size_t size);
 static void*HeapTracked::operator new[](std::size_t nSize);
 static void operator delete(void *ptr);
// static void operator delete[](void *ptr);
 static void operator delete[](void *ptr);
 bool isOnHeap()const;
};
template<class CHILD_TYPE>
std::map<const int,const void *> HeapTracked<CHILD_TYPE>::pointerMap;//静态对象在类外仍需定义
template<class CHILD_TYPE>
HeapTracked<CHILD_TYPE>::HeapTracked(const HeapTracked<CHILD_TYPE> &refDerivedObj):ObjSize(sizeof(refDerivedObj)){
 try{
  const void*rawAddressHeapTracked=dynamic_cast<const void*>(this);
  const void*rawAddressDerivedObj=dynamic_cast<const void*>(&refDerivedObj);
  if(rawAddressHeapTracked!=rawAddressDerivedObj)
  {
   std::cout<<"子类初始化HeapTracked时,所传参数必须是this指针或者*this"<<std::endl;
  }
 }
 catch(...){
  std::cout<<"子类初始化HeapTracked时,所传参数必须是this指针或者*this"<<std::endl;
  exit(0);
 }

template<class CHILD_TYPE>
HeapTracked<CHILD_TYPE>::HeapTracked(CHILD_TYPE *pDerivedObj):ObjSize(sizeof(*pDerivedObj)){
 try{
  const void*rawAddressHeapTracked=dynamic_cast<const void*>(this);
  const void*rawAddressDerivedObj=dynamic_cast<const void*>(pDerivedObj);
  if(rawAddressHeapTracked!=rawAddressDerivedObj)
  {
  std::cout<<"子类初始化HeapTracked时,所传参数必须是this指针或者*this"<<std::endl;
  }
 }
 catch(...){
  std::cout<<"子类初始化HeapTracked时,所传参数必须是this指针或者*this"<<std::endl;
  exit(0);
 }

template<class CHILD_TYPE>
HeapTracked<CHILD_TYPE>::~HeapTracked(){//纯虚的析构函数必须要有再定义
}
template<class CHILD_TYPE>
void*HeapTracked<CHILD_TYPE>::operator new(std::size_t size){
 void*memPtr=::operator new(size);//分配内存
 try{
  pointerMap.insert(std::make_pair((const int)memPtr,(const void*)memPtr));//把地址插入map中
 }catch(...)
 {
  std::cout<<"map中插入pair失败!"<<std::endl;
  exit(0);
 }
 return memPtr;
}

template<class CHILD_TYPE>
void*HeapTracked<CHILD_TYPE>::operator new[](std::size_t nSize)
{
 void*memPtr=::operator new[](nSize);//分配内存

 {
  char *singleObjAddress=(char*)memPtr+sizeof(int);
  for(unsigned int i=0,ptrStepSize=sizeof(CHILD_TYPE),
   objCount=nSize/ptrStepSize;i<objCount;i++)
  {
   try{
     //向map插入每个对象的地址
     pointerMap.insert(std::make_pair((const int)singleObjAddress,(const void*)singleObjAddress));
     singleObjAddress+=ptrStepSize;//得到每个对象的地址
   }catch(...)
   {
    std::cout<<"map中插入pair失败!"<<std::endl;
    singleObjAddress=NULL;
    exit(0);
   }
  }
  singleObjAddress=NULL;
 }

 return memPtr;
}
template<class CHILD_TYPE>
void HeapTracked<CHILD_TYPE>::operator delete(void*ptr){
 if(ptr==0)return;
 //在map中查找是否有这个指针
 std::map<const int,const void *>::iterator iter=pointerMap.find((const int)ptr);
 if (iter != pointerMap.end()) { //若找到,说明指针指向了堆上的内存
  pointerMap.erase(iter);//从map中移除这个指针
  ::operator delete(ptr);//释放指针指向的内存
 }else{//否则ptr不是一个堆对象的指针,不能调用operatordelete,抛出异常
  throw MissingAddress();
 }
}
//template<class CHILD_TYPE>
//void HeapTracked<CHILD_TYPE>::operator delete[](void *ptr);
template<class CHILD_TYPE>
void HeapTracked<CHILD_TYPE>::operator delete[](void *ptr){
 if(ptr==0){return;}

 {
  char *singleObjAddress=(char *)ptr+sizeof(int);
  for(unsigned int i=0,objCount=*(int *)ptr,ptrStepobjCount=sizeof(CHILD_TYPE);i<objCount;i++)
  {
    std::map<const int,const void *>::iterator iter=pointerMap.find((const int)singleObjAddress);
    if (iter != pointerMap.end()) { //若找到,说明指针指向了堆上的内存
     pointerMap.erase(iter);//从map中移除这个指针
     singleObjAddress+=ptrStepobjCount;
    }else{//否则ptr不是一个堆对象的指针,不能调用operatordelete,抛出异常
     singleObjAddress=NULL;
     throw MissingAddress();
    }  
  }
  singleObjAddress=NULL;
 }
 ::operator delete[](ptr);//释放指针指向的内存
}
template<class CHILD_TYPE>
bool HeapTracked<CHILD_TYPE>::isOnHeap()const{
 //获取*this对象的真正内存起始地址
 const void*rawAddress=dynamic_cast<const void*>(this);
 //在map中查找this指针
 std::map<const int,const void *>::iterator iter=pointerMap.find((const int)rawAddress);
 return iter != pointerMap.end();//若找到,说明指针指向了堆上的内存
}
//class A:public HeapTracked<A>
//{
//public:
// A():HeapTracked<A>(this){
//  int kk=0;
// }
//};
//class B:public HeapTracked<A>
//{
//public:
// A a;
// //初始化时只能为本类的当前对象,因为如果为其他类型的对象是不可以的,因为HeapTracked已经初始化
// //为本类的对象,
// B():HeapTracked<A>(&a){
// int kk=0;
// }
//};
 template<class T, class B> struct Derived_from {
  static void constraints(T* p) { B* pb = p; }
  Derived_from() { void(*p)(T*) = constraints; }
 };//www.stroustrup.com静态编译时类型检测最佳方案

 template<class T1, class T2> struct Can_copy {
  static void constraints(T1 a, T2 b) { T2 c = a; b = a; }
  Can_copy() { void(*p)(T1,T2) = constraints; }
 };//www.stroustrup.com静态编译时类型检测最佳方案

 template<class T1, class T2 = T1> struct Can_compare {
  static void constraints(T1 a, T2 b) { a==b; a!=b; a<b; }
  Can_compare() { void(*p)(T1,T2) = constraints; }
 };//www.stroustrup.com静态编译时类型检测最佳方案

 template<class T1, class T2, class T3 = T1> struct Can_multiply {
  static void constraints(T1 a, T2 b, T3 c) { c = a*b; }
  Can_multiply() { void(*p)(T1,T2,T3) = constraints; }
 };//www.stroustrup.com静态编译时类型检测最佳方案
template <typename Der>
class intermediate:public HeapTracked<Der>
{
public:
  intermediate(Der * Der_thisPtr):HeapTracked(Der_thisPtr){
   Derived_from<Der,intermediate>();
 }
  intermediate(const intermediate<Der>& Der_RefThis):HeapTracked(Der_RefThis){
   Derived_from<Der,intermediate>();
 }
};
//若要从OneRowDataOfCompany派生新类,请仿照intermediate,重新定义OneRowDataOfCompany模版类
//最下端的继承样式如现在的OneRowDataOfCompany类定义
class OneRowDataOfCompany:public intermediate<OneRowDataOfCompany>
{
private:
 
 int RuKuMonth;
 double RuKuJinEValue;
 CString NaShuiRenBianMa;
 CString NaShuiRenMingChen;
 CString ZhengShouXiangMu;
 CString RuKuJinE;
 CString RuKuJinEComment;
public:
 OneRowDataOfCompany():intermediate(this){}
 OneRowDataOfCompany(const intermediate<OneRowDataOfCompany> &):intermediate(*this){}
 int Get_RuKuMonth()const{return RuKuMonth;}; //注意这里的const,因为Get函数一般不需要修改对象自身
 double Get_RuKuJinEValue()const{return RuKuJinEValue;};
 CString Get_NaShuiRenBianMa()const{return NaShuiRenBianMa;};
 CString Get_NaShuiRenMingChen()const{return NaShuiRenMingChen;};
 CString Get_ZhengShouXiangMu()const{return ZhengShouXiangMu;};
 CString Get_RuKuJinE()const{return RuKuJinE;};
 CString Get_RuKuJinEComment()const{return RuKuJinEComment;};
 void Set_RuKuMonth(int ParaRuKuMonth){RuKuMonth=ParaRuKuMonth;};
 void Set_RuKuJinEValue(double ParaRuKuJinEValue){ RuKuJinEValue=ParaRuKuJinEValue;};
 void Set_NaShuiRenBianMa(CString &ParaNaShuiRenBianMa){ NaShuiRenBianMa=ParaNaShuiRenBianMa;};
 void Set_NaShuiRenMingChen(CString &ParaNaShuiRenMingChen){ NaShuiRenMingChen=ParaNaShuiRenMingChen;};
 void Set_ZhengShouXiangMu(CString &ParaZhengShouXiangMu){ ZhengShouXiangMu=ParaZhengShouXiangMu;};
 void Set_RuKuJinE(CString &ParaRuKuJinE){ RuKuJinE=ParaRuKuJinE;};
 void Set_RuKuJinEComment(CString &ParaRuKuJinEComment){ RuKuJinEComment=ParaRuKuJinEComment;};

};



猜你喜欢

转载自blog.csdn.net/tom_xuzg/article/details/38348999