您的位置:首页 > 编程语言 > C语言/C++

浅谈C++之重载new和delete

2020-03-05 09:14 826 查看

文章目录

概述

某些应用程序对内存分配有特殊的需求,因此我们无法将标准内存管理机制直接应用于某些程序。它们常常需要自定义内存分配的细节,比如使用关键字new将对象放置在特定的内存空间中。为了实现这一目的。应用程序需要重载new运算符和delete运算符以控制内存分配过程。

工作机制

尽管我们说能够“重载new和delete”,但是实际上重载这两个运算符与重载其他运算符的过程大不相同。要想真正掌握重载new和delete的方法,首先要对new表达式和delete表达式的工作机理有更多的了解。
当我们使用一条new表达式的时候:

//new表达式
string *sp = new string("a value");//分配并初始化一个string对象
string *arr = new string[10]p;//分配10个默认初始化的string对象

实际执行了三步操作。第一步,new表达式调用一个名为operator new (或者operator new[])的标准库函数。该函数分配一块足够大的、原始的、未命名的内存空间以便存储特定类型的对(或者对象的数组)。第二步,编译器运行相应的构造函数以构造这些对象,并为其传入初始值。第三步,对象被分配了空间并构造完成,返回一个指向该对象的指针。

//当我们使用一条delete表达式删除一个动态分配的对象时:
delete sp;//销毁sp,然后释放sp指向的内存空间
delete [] arr;//销毁数组中的元素,然后释放对应的内存空间

如果应用程序希望控制内存分配的过程,则它们需要定义自己的operator new 函数和operator delete 函数。即使在标准库中已经存在这两个函数的定义,我们仍旧可以定义自己的版本。编译器不会对这种重复的定义提出异议,相反,编译器将使用我们自定义的版本替换标准库定义的版本。
注意
当定义了全局的opeartor new 函数和operator delete函数后,我们就担负起了控制动态内存分配的职责。这两个函数必须是正确的:因为它们是程序整个处理过程中至关重要的一部分。

应用程序可以在全局作用域中定义operator new函数和opertor delete函数,也可以将它们定义为成员函数。当编译器发现一条new表达式或delete表达式后,将在程序中查找可供调用的operator函数。如果被分配 (释放)的对象是类类型,则编译器首先在类及其基类的作用域中查找。此时如果该类含有operator new 成员或operator delete成员,则相应的表达式将调用这些成员。否则,编译器在全局作用域查找匹配的函数。此时如果编译器找到了用户自定义的版本,则使用该版本在全局作用域查找匹配的函数。此时如果编译器找到了用户自定义的版本,则使用该版本执行new 表达式或delete表达式;如果没找到。则使用标准库定义的版本。

我们可以使用作用域运算符指令new表达式或delete表达式忽略定义在类中的函数,直接执行全局作用域中的版本。
例如

::new //只在全局作用域中查找匹配的operator new 函数
  • 点赞
  • 收藏
  • 分享
  • 文章举报
百度云服务 发布了58 篇原创文章 · 获赞 12 · 访问量 1535 私信 关注
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: