#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;};
};