类的operator new与operator delete的重载

简介:

为什么有必要写自己的operator new和operator delete?

答案通常是:为了效率。
缺省版本的operator new是一种通用型的内存分配器,它必须可以分配任意大小的内存块。同样,operator delete也要可以释放任意大小的内存块。operator delete想弄清它要释放的内存有多大,就必须知道当初operator new分配的内存有多大。有一种常用的方法可以让operator new来告诉operator delete当初分配的内存大小是多少,就是在它所返回的内存里预先附带一些额外信息,用来指明被分配的内存块的大小。
缺省的operator new和operator delete具有非常好的通用性,它的这种灵活性也使得在某些特定的场合下,可以进一步改善它的性能。尤其在那些需要动态分配大量的但很小的对象的应用程序里,情况更是如此。

内存池:内存池的作用主要也是为了效率。通过一次申请比较大的内存空间,来避免小空间内存的频繁申请和释放,每次需要为对象分配内存空间时,在已经申请的大空间内分配。空闲区被按照对象大小划分为若干块,块与块之间通过链表组织起来。

参考代码:

View Code

airplane类的说明:

airplane实际上是个句炳类(Handle class),通过指针airplanerep * rep指向一个具体的实现,airplane和airplanerep含有一样的成员函数。句柄类实际上都做了些什么:它只是把所有的函数调用都转移到了对应的主体类中,主体类真正完成工作。
operator new函数负责内存池链表的创建,内存池链表的每个块大小和类airplane一样,每次生成对象的时候分配一个块给对象。
operator delete函数负责收回每个对象的内存块,重新添加到内存池链表。
operator new和operator delete需要同时工作,那么你写了operator new,就也一定要写operator delete。
一个联合(使得rep和next域占用同样的空间),一个常量(指定大内存块的大小),一个静态指针(跟踪自由链表的表头)。表头指针声明为静态成员很重要,因为整个类只有一个自由链表,而不是每个airplane对象都有。
注意:::operator new返回的内存块是从来没有被airplane::operator delete释放。内存泄漏和内存池有一个重要的不同之处:内存泄漏会无限地增长,而内存池的大小决不会超过客户请求内存的最大值。

以上内容基本都来自《Effective C++》,稍作修改。

如果类定义了自己的成员new和delete,类的用户可以通过使用全局作用域确定操作符,强制new和delete使用全局的库函数。如:
Type *p = ::new Type;
::delete p;

如果new使用全局的operator new库函数,那么对应的delete也一定要用全局的operator delete库函数。

一个内存分配器基类

CachedObj的功能:类似于内存池的功能。分配和管理已经分配但未构造对象的自由列表。operator new返回自由列表中的一个元素,当自由列表为空时,operator new分配新的原始内存。operator delete在撤销对象时将元素放回自由列表。

View Code

如何使用这个类:

View Code

    本文转自阿凡卢博客园博客,原文链接: http://www.cnblogs.com/luxiaoxun/archive/2012/08/11/2633423.html ,如需转载请自行联系原作者

相关文章
|
7月前
|
存储 算法 编译器
【C++ 内存管理 重载new/delete 运算符 新特性】深入探索C++14 新的/删除的省略(new/delete elision)的原理与应用
【C++ 内存管理 重载new/delete 运算符 新特性】深入探索C++14 新的/删除的省略(new/delete elision)的原理与应用
182 0
|
安全 C++
【C++11保姆级教程】移动构造函数(move constructor)和移动赋值操作符(move assignment operator)
【C++11保姆级教程】移动构造函数(move constructor)和移动赋值操作符(move assignment operator)
788 0
|
1月前
|
JavaScript 前端开发 开发者
call 方法和 apply 方法的区别是什么?
【10月更文挑战第26天】`call` 方法和 `apply` 方法的主要区别在于参数传递方式和使用场景。开发者可以根据具体的函数参数情况和代码的可读性、简洁性要求来选择使用 `call` 方法还是 `apply` 方法,以实现更高效、更易读的JavaScript代码。
35 2
|
3月前
|
C++
C++(十)operator=
本文档介绍了 C++ 中赋值运算符 `operator=` 的重载方法,包括其概念、语法格式及特性,并通过实现一个 `mystring` 类展示了具体的代码示例。赋值运算符用于将一个已创建的对象赋值给另一个已创建的对象,需注意自赋值、内存泄漏和重析构等问题。文档中的 `mystring` 类实现了字符串对象的赋值、拼接及比较等功能。
|
6月前
|
Python
operator.floordiv
【6月更文挑战第27天】
27 2
|
7月前
|
JavaScript 前端开发
call函数和apply函数的区别
call函数和apply函数的区别
57 0
|
存储 编译器 C语言
C++:类和对象(中)---默认成员函数---运算符重载---const的含义
C++:类和对象(中)---默认成员函数---运算符重载---const的含义
解决办法:对‘operator delete(void*)’未定义的引用
解决办法:对‘operator delete(void*)’未定义的引用
198 0
尽量以non-member non-friend函数替换成员函数
尽量以non-member non-friend函数替换成员函数
162 0