C++编程思想--动态创建对象(2)
来源:互联网 发布:淘宝卖衣服从哪里进货 编辑:程序博客网 时间:2024/06/12 20:05
动态创建对象(2)
5)重载new 与delete,首先为什么需要重载new与delete呢?
① 也许要创建和销毁一个类的非常多的对象,以至于这个影响到了速度。
② 分配不同大小的内存可能会产生碎片,内存很快就被分配完
所以重载的时候我们只是改变了原来的分配方法,当重载时可以替换原来内存消耗完之后的行为。所以在operator new 中要决定是返回0,还是调用new-hander的循环。或者产生异常的消息。我们可以选择重载全局内存分配函数或者是针对于某个类。
(1)这是重载全局的new以及delete之后的程序以及运行结果:
#include <cstdio>#include <cstdlib>#include <iostream>using namespace std;void * operator new(size_t sz)//1.size_t 的类型是?标准C库中定义的,应为unsigned int,它是一种“整型”类型,{ //里面保存的是一个整数,就像int, long那样。//printf("operator new :%d Bytes\n",sz);//2.这里使用的是printf,而不是cout,因为它是一个iostream对象,会调用new去分配内存,于是产生死锁cout<<"operator new "<<sz<<endl;void *m=malloc(sz);//3.申请空间返回的是void* 类型,所以它所做的只是分配内存,而非完成一个对象的创建。对象的创建要等到编译器调用构造函数才完成if (!m){puts("out of memeory");}return m;}void operator delete(void *m)//参数是void* 这是调用析构函数后得到的指针,也就是说析构函数会从构造函数中获得内存的指针{ //返回类型为void puts("operator delete"); free(m);}class S{int i[100];public:S(){puts("S::S()");//}//void operator delete[](void *m)//这种方式可以删除对象数组//{//puts("operator array delete");//::delete []m;//}~S(){puts("S::~S()");}};int GlobalOperatorNewTest(){puts("creating & destorying an int");int *p=new int(47);delete p;puts("creating &destorying an S");S *s=new S;delete s;puts("creating &destorying S[3]");S *sa=new S[3];//4.这里会多出空间,用于存放数组的信息,也就是说对象的数量的信息。delete []sa;return 0;}
结果:
从结果中我们可以看到首先会调用new然后再调用的是构造函数。调用了析构函数之后才会调用deleted函数。但是我们看到在释放对象数组的时候并没有调用我们自己定义的deleted函数。而是调用的系统的delete[],
那么如果在类中对数组进行delete的重载如下:
void operator delete[](void *m)//这种方式可以删除对象数组{puts("operator array delete");::delete []m;}
这是进行重载数组的delete函数之后的执行结果
(1)也可以在类中进行new的重载,只是针对这个类。
代码:
//operator new local#include <cstddef>#include <fstream>#include <iostream>#include <new>using namespace std;ofstream out("Framis01.txt");class Framis{enum{sz=10};char c[sz];static unsigned char pool[];static bool alloc_map[];public:enum{prize=100};Framis(){out<<"Framis()\n";}~Framis(){out<<"~Framis()...";}#pragma warning( disable : 4290 ) void *operator new (size_t) throw(bad_alloc);void operator delete(void *);};unsigned char Framis::pool[prize*sizeof(Framis)];bool Framis::alloc_map[prize]={false};void * Framis::operator new(size_t )throw(bad_alloc)//参数后面带throw告诉编译器可以产生一个bad_alloc的异常消息。且若没有内存可以使用,也会由{ //bad_alloc产生一个异常消息。 //使用类的这种创建方法,可以减少内存碎片。那么释放掉的内存可以重新使用for (int i=0;i<prize;i++){if(!alloc_map[i])//判断这块内存有没有被使用,{out<<"using block"<<i<<"...";alloc_map[i]=true;//没有使用的话,将其置为truereturn pool+(i*sizeof(Framis));//返回地址}}cout<<"out of memeory"<<endl;throw bad_alloc();}void Framis::operator delete(void *m){if(!m)//确保是地址在堆内是在正确的地址范围之内,因为很可能我们删除的是数组,然而忘记加上[]。return;unsigned long block=(unsigned long)m-(unsigned long)pool;block/=sizeof(Framis);out<<"freeing block "<<block<<endl;//释放对应的地址空间.alloc_map[block]=false;}int main(){Framis *f[Framis::prize];try{for (int i=0;i<Framis::prize;i++){f[i]=new Framis ;}new Framis;}catch(bad_alloc)//在这里接收内存申请失败的信息。{cerr<<"Out of memory!"<<endl;}delete f[10];//这是调用全局版本的delete.f[10]=0;//删除对应的空间内容,并且使这个指针的值为0.Framis *x=new Framis;//当重新创建一个对象,对象的内容将会被放在f[10]所指的内存中,这样就充分的利用资源delete x;for (int j=0;j<Framis::prize;j++){delete f[j];}}
运行结果:
可以看到释放的内存重新被利用起来。下面是txt中的一部分内容
using block99...Framis()
~Framis()...freeing block 10
using block10...Framis()
~Framis()...freeing block 10
(1)定位new.也就是确定在哪个位置上进行分配内存,也就是可以向New函数中传递参数,但是对于delete是不能传递的,它是与new对应的。
小结:1、C中的malloc虽然可以使用但是不安全,
2、如果对内存要求很高的时候我们不妨使用自己定义的new来申请内存空间
- C++编程思想--动态创建对象(2)
- C++编程思想(2nd卷一):动态对象创建
- C++编程思想(2nd卷一):动态对象创建
- C++编程思想--动态对象的创建(1)
- C++编程思想学习——动态对象创建
- C++编程思想笔记——动态对象创建
- 《C++编程思想》 第十二章 动态对象创建 (原书代码+习题+解答)
- java对象的创建过程(摘自《java编程思想》)
- C++编程思想学习笔记---第13章 动态创建对象
- 面向对象编程的思想(2)
- (C#)利用反射动态调用类成员、动态加载控件以及插件编程思想
- (C#)利用反射动态调用类成员、动态加载控件以及插件编程思想
- 《C++编程思想》(第二版)第2章 对象的创建和使用(习题及答案)
- c++编程思想-第2章 对象的创建与使用-2
- C++编程思想学习-对象的创建与使用
- C++编程思想 第二章对象的创建和使用
- C++编程思想 第二章 对象的创建与使用
- 对象的创建过程(来自《java编程思想》)
- Java乔晓松-利用JavaScript实现js对user用户的分页和实现js对用户的增删改查操作
- UVA 10714 - Ants
- 黑马程序员-HTML网页知识
- 自画Caption标题栏
- 数据结构--栈
- C++编程思想--动态创建对象(2)
- 1306
- linux硬链接与软链接 linux asm 文件
- 领域驱动设计之代码优先-架构描述 (翻译)
- Java程序性能优化
- PHP, 不要使用(include/require)_once
- 黑马程序员---java基础之IO(字符流和字节流)
- 企业Beans Enterprise Beans
- PAT1008. Elevator