【Windows核心编程】重载类成员函数new / new[] / delete / delete[]
// Heap.cpp : 定义控制台应用程序的入口点。
// #include "stdafx.h"
#include <Windows.h>
#include <iostream>
#include <new>
using namespace std; int* p = new int(); class CSomeClass
{
protected:
static size_t s_Counts;
static HANDLE s_hHeap; public:
CSomeClass();
CSomeClass(int value);
virtual ~CSomeClass(); //重载的该运算符为该类的成员函数
//所以 这里的size_t参数分配的字节数不必显示指定,该参数为sizeof(该类)
void* operator new(size_t);
//void* operator new(size_t, const char* fileName, int line);
void* operator new[](size_t); void operator delete(void* p);
void operator delete[](void* p);
//void operator delete(void* p, const char* fileName, int line); int m_value; }; size_t CSomeClass::s_Counts = ;
HANDLE CSomeClass::s_hHeap = NULL;
CSomeClass::CSomeClass(){} CSomeClass::CSomeClass(int value) : m_value(value){} CSomeClass::~CSomeClass(){} void* CSomeClass::operator new(size_t size)
//void* CSomeClass::operator new(size_t size, const char* fileName, int line)
{
//cout<<endl<<fileName<<", line "<<line<<endl; //如果是第一个实例,则创建堆
if (NULL == s_hHeap)
{
s_hHeap = HeapCreate(HEAP_GENERATE_EXCEPTIONS, , );
if (NULL == s_hHeap)
{
return NULL;
}
} void* p = HeapAlloc(s_hHeap, HEAP_ZERO_MEMORY | HEAP_GENERATE_EXCEPTIONS, size);
if (NULL != p)
{
++s_Counts;
} return p;
} void* CSomeClass::operator new[](size_t size)
{
//size大小为 sizeof(CSomeClass) * 个数 + 额外信息的大小 //注意,这里这种做法可能会有问题,只有当额外信息的大小 小于 对象大小时才合理!!! //nums为对象的个数
size_t nums = size / sizeof(CSomeClass); //sizeOfExtra的大小为存储额外信息的空间大小
size_t sizeOfExtra = size % sizeof(CSomeClass); if (NULL == s_hHeap)
{
s_hHeap = HeapCreate(HEAP_GENERATE_EXCEPTIONS, , );
if (NULL == s_hHeap)
{
return NULL;
}
} void* p = HeapAlloc(s_hHeap, HEAP_ZERO_MEMORY | HEAP_GENERATE_EXCEPTIONS, size);
if (NULL != p)
{
s_Counts += nums;
} return p;
} void CSomeClass::operator delete(void* p)
//void CSomeClass::operator delete(void* p, const char* fileName, int line)
{
if (NULL == p || NULL == s_hHeap)
{
return;
} BOOL bRet = HeapFree(s_hHeap, , p);
if (FALSE != bRet)
{
if (--s_Counts == )
{
HeapDestroy(s_hHeap);
//CloseHandle(s_hHeap); //保留这一行 有异常 invalid handle
s_hHeap = NULL;
}
}
} void CSomeClass::operator delete[](void* p)
{
if (NULL == p || NULL == s_hHeap)
{
return;
} size_t size = HeapSize(s_hHeap, , p);
size_t nums = size / sizeof(CSomeClass);
size_t sizeOfExtra = size % sizeof(CSomeClass); BOOL bRet = HeapFree(s_hHeap, , p);
if (FALSE != bRet)
{
if ( == (s_Counts -= nums))
{
HeapDestroy(s_hHeap);
s_hHeap = NULL;
}
}
} #ifdef _DEBUG
//#define new new(__FILE__, __LINE__)
//#define delete delete(__FILE__, __LINE__)
#endif int __cdecl _tmain(int argc, _TCHAR* argv[], _TCHAR* env[])
{
HANDLE hHeaps[] = {NULL};
DWORD dwHeaps = GetProcessHeaps(sizeof(hHeaps) / sizeof(hHeaps[]), hHeaps); CSomeClass* pAddr2 = new CSomeClass[]();
dwHeaps = GetProcessHeaps(sizeof(hHeaps) / sizeof(hHeaps[]), hHeaps);
delete[] pAddr2;
dwHeaps = GetProcessHeaps(sizeof(hHeaps) / sizeof(hHeaps[]), hHeaps); #pragma region 测试1
int size = sizeof(CSomeClass);
cout<<"sizeof(CSomeClass) is "<<size<<endl; CSomeClass* pObj = new CSomeClass(size * );
pObj->m_value = ;
CSomeClass* pObj2 = new CSomeClass();
pObj2->m_value = ; delete pObj;
//delete pObj2;
#pragma endregion CSomeClass* pArr = new CSomeClass[]; //UINT HeapCompact(HANDLE hHeap, DWORD fdwFlags)
//BOOL HeapLock(HANDLE hHeap);
//BOOL HeapUnLock(HANDLE hHeap);
//BOOL HeapWalk(HANDLE hHEap, PROCESS_HEAP_ENTRY pHeapEntry)
/*
BOOL bRet = FALSE;
PROCESS_HEAP_ENTRY phe;
phe.lpData = NULL; HeapLock(hHeap);
while(TRUE == (bRet = HeapWalk(hHeap, 0, &phe))
{
//do something
phe.lpData = NULL;
} HeapUnLock(hHeap); */ return ;
} /*
int _tmain(int argc, _TCHAR* argv[])
{
HANDLE hHeap = HeapCreate(HEAP_GENERATE_EXCEPTIONS, 0, 0);
if (NULL == hHeap)
{
cerr<<"Create heap error \n";
return -1;
} //BOOL bRet = HeapSetInformation(hHeap, HeapEnableTerminationOnCorruption, NULL, 0); ULONG HeapInformationValue = 2;
BOOL bRet = HeapSetInformation(
hHeap, HeapCompatibilityInformation, &HeapInformationValue, sizeof(HeapInformationValue)); size_t size = 100;
PVOID pAddr = HeapAlloc(hHeap, HEAP_ZERO_MEMORY | HEAP_GENERATE_EXCEPTIONS, size);
if(NULL == pAddr)
{
HeapFree(hHeap, 0, pAddr); //释放申请的内存快
HeapDestroy(hHeap); //销毁堆
CloseHandle(hHeap); //关闭句柄
cerr<<"HeapAlloc error \n";
return -2;
} *((int*)(pAddr)) = 100;
cout<<"int pAddr is "<<*((int*)(pAddr))<<endl; cout<<"alloc size of heap is "<<HeapSize(hHeap, 0, pAddr)<<endl; PVOID pAddr2 = HeapReAlloc(hHeap, HEAP_GENERATE_EXCEPTIONS | HEAP_ZERO_MEMORY | HEAP_REALLOC_IN_PLACE_ONLY,
pAddr, size * 20);
if (NULL == pAddr2)
{
HeapFree(hHeap, 0, pAddr);
HeapDestroy(hHeap);
CloseHandle(hHeap);
cerr<<"HeapReAlloc error \n"; return -3;
}
cout<<"int pAddr2 is "<<*((int*)(pAddr2) + 1)<<endl; cout<<"Realloc size of heap is "<<HeapSize(hHeap, 0, pAddr2)<<endl; HeapFree(hHeap, 0, pAddr2);
HeapDestroy(hHeap);
CloseHandle(hHeap);
cout<<"Heap opera is finish "<<endl; return 0;
} */
【Windows核心编程】重载类成员函数new / new[] / delete / delete[]的更多相关文章
- 重载运算符:类成员函数or友元函数
类成员函数: bool operator ==(const point &a)const { return x==a.x; } 友元函数: friend bool operator ==(co ...
- C++类成员函数的重载、覆盖和隐藏区别?
C++类成员函数的重载.覆盖和隐藏区别? a.成员函数被重载的特征:(1)相同的范围(在同一个类中):(2)函数名字相同:(3)参数不同:(4)virtual 关键字可有可无.b.覆盖是指派生类函数覆 ...
- C++类成员函数的 重载、覆盖和隐藏区别
重载:成员函数被重载的特征: (1)相同的范围(在同一个类中): (2)函数名字相同: (3)参数不同: (4)virtual 关键字可有可无. #include <iostream> u ...
- C++:类成员函数的重载、覆盖和隐藏区别?
#include <iostream> class A { public: void func() { std::cout << "Hello" <& ...
- 并发编程: c++11 thread(Func, Args...)利用类成员函数创建线程
c++11是VS2012后支持的新标准,为并发编程提供了方便的std::thread. 使用示例: #include <thread> void thread_func(int arg1, ...
- 【非原创】C++类成员函数的重载、覆盖和隐藏
链接:https://www.nowcoder.com/questionTerminal/266d3a6d4f1b436aabf1eff3156fed95来源:牛客网 题目:类成员函数的重载.覆盖和隐 ...
- c++类成员函数重载常量与非常量版本时避免代码重复的一种方法
c++有时候需要为类的某个成员函数重载常量与非常量的版本,定义常量版本是为了保证该函数可作用于常量类对象上,并防止函数改动对象内容.但有时两个版本的函数仅仅是在返回的类型不同,而在返回前做了大量相同的 ...
- 类成员函数的重载、覆盖和隐藏区别 (C++)(转)
类成员函数的重载.覆盖和隐藏区别 (C++) 这是本人第一次写博客,主要是想记录自己的学习过程.心得体会,一是可以方便以后回顾相关知识,二是可以与大家相互学习交流. 关于C++中类成员函数的重载. ...
- python2学习------基础语法3(类、类的继承、类成员函数、防御式编程)
1.类的定义以及实例化 # 类定义 class p: """ this is a basic class """ basicInfo={&q ...
随机推荐
- 不要将缓存服务器与Tomcat放在单台机器上,否则出现竞争内存问题
缓存分为本地缓存和远程分布式缓存,本地缓存访问速度更快但缓存数据量有限,同时存在与应用程序争用内存的情况. 1.不要将缓存服务器与Tomcat放在单台机器上,否则出现竞争内存问题 2.不要将缓存服务器 ...
- iOS动画篇:UIView动画
iOS的动画效果一直都很棒很,给人的感觉就是很炫酷很流畅,起到增强用户体验的作用.在APP开发中实现动画效果有很多种方式,对于简单的应用场景,我们可以使用UIKit提供的动画来实现. UIView动画 ...
- Java学习笔记之:java运算符
一.介绍 计算机的最基本用途之一就是执行数学运算,作为一门计算机语言,Java也提供了一套丰富的运算符来操纵变量.我们可以把运算符分成以下几组: 算术运算符 关系运算符 位运算符 逻辑运算符 赋值运算 ...
- Failed to execute goal.....webxml attribute is required...
maven在打包项目的时候报错 Failed to execute goal org.apache.maven.plugins:maven-war-plugin:2.2:war (default-wa ...
- Eclipse项目和MyEclipse项目
因为Eclipse的项目结构和MyEclipse项目的结构不同,所以两者的项目之间不能直接运行的. 我们在创建Eclipse项目的时候可以进行一些设置,这样在Eclipse中创建的项目可以直接在MyE ...
- python 有关矩阵行列的存取 np.array
初始化 a = range() a = np.array(a) a = a.reshape(,) a [[ 0 1 2 3] [ 4 5 6 7] [ 8 9 10 11] [12 ...
- Javascript如何判断一个变量是数字类型?
isNaN()不能判断一个变量是否为数字类型,isNaN(123)值为false,isNaN('123')值也为false.isNaN() 的实际作用跟它的名字isNaN并不一致,isNaN(NaN) ...
- 24-语言入门-24-cigarettes
题目地址: http://acm.nyist.edu.cn/JudgeOnline/problem.php?pid=94 描述Tom has many cigarettes. We hypoth ...
- StaggeredGridLayoutManager
Class Overview A LayoutManager that lays out children in a staggered grid formation. It supports hor ...
- WPF中的Drawing
以前在用WinForm的时候,可以通过GDI+接口在窗体上动态绘制自定义的图形.在WPF中有没有对应的API呢,最近项目中用到了这个,在这里总结一下. WPF中的Drawing主要提供了几类API: ...