1. operator new、operator delete与new、delete操作符的区别:

  • operator new的作用类似于malloc,负责分配内存;operator delete的作用类似于free,负责释放内存
  • new操作符包括两个步骤;调用适当的operator new版本分配内存;在分配的内存上调用构造函数
  • delete操作符包括两个步骤:在内存上调用析构函数;调用适当的operator delete版本释放内存
  • operator new和operator delete函数可以重载、重写(名字遮掩),而new/delete操作符不可

2. 标准库提供的operator new/delete(C++11)

标准库提供的global operator new,在全局名字空间中定义:
    void* operator new (std::size_t size); //抛出异常的版本
void* operator new (std::size_t size, const std::nothrow_t& nothrow_value) noexcept; //不抛出异常的版本,内存不足则返回nullptr
void* operator new (std::size_t size, void* ptr) noexcept; //placement new,仅仅返回ptr值,未作内存分配

对应的global operator delete:

    void operator delete (void* ptr) noexcept;
void operator delete (void* ptr, const std::nothrow_t& nothrow_constant) noexcept;
void operator delete (void* ptr, void* voidptr2) noexcept;//本函数未做任何事情

3. operator new与operator delete:层次关系、版本、对应关系与new handler

  • 层次关系:C++标准中仅建议在两种“作用域”中定义operator new/delete,即在类中作为类的static成员或在global作用域中。在使用Class1 *pc = new Class1;的形式创建动态对象时,new操作符首先在当前类(Class1)中查找operator new的相应版本,若未找到,则会到基类中递归查找,若还未找到,则会到global作用域中查找。查找过程中使用“名字遮掩规则”
  • 版本:
    1. 标准版:标准版的operator new只有一个size_t类型的参数;标准版的operator delete只有 void*类型参数;另外,operator delete还有一个特别成员版:有void *类型参数和size_t类型参数(只可在class中定义)。若类中同时定义了这两种operator delete,则优先使用前者。
    2. 非标准版:Effective C++中称之为placement版,并指出其多义性,而C++标准中将placement语义留给了上述提到标准库的第三个函数。非标准版的operator new可以有除了第一个size_t参数以外的其他参数,原型形式为:void* operator new(std::size_t size, type1 arg1, type2 arg2...); 通过new操作符间接调用的形式为: new(arg1, arg2, ...)ClassX; 非标准版的operator delete除了有第一个void*类型的参数还有额外的参数,其原型形式为:void* operator delete(void *ptr, type1 arg1, type2 arg2 ...); 非标准版的operator delete会在相应的operator new调用后对象的构造函数发生异常时由编译器调用。
    3. 注:关于operator delete的“特别成员版”。若类中同时有标准形式的operator delete作为成员,则delete操作符优先使用标准形式的operator delete,即时在异常抛出(下文会解释这是什么异常情况)时也是如此。另外,非标准版的operator new并没有与之参数对应的“特别成员版”
不同形式的operator new与operator delete:
    void* operator new (std::size_t size); //全局标准版operator new
void operator delete(void* ptr);//全局标准版operator delete
class A{
public:
static void operator new(size_t size);//类专属标准版operator new
static void operator delete(void* ptr, size_t size) noexcept;//类特别成员版operator delete
static void operator delete(void* ptr) noexcept;//类专属operator delete
};
  • 对应关系:
    1. 标准版:void* operator new(std::size_t size)可与两种operator delete对应,即void operator delete(void* ptr)或void operator delete(void*ptr, size_t)。且无论在正常情况下,还是异常情况下,C++优先使用第一种operator delete
    2. 非标准版:void* operator new(std::size_t size, ...)与void operator delete(void* ptr, ...)对应。未发生异常时,C++编译器调用operator new(标准版或非标准版依据new操作符是否传递额外参数而定)分配内存,调用标准版的operator delete(无论该内存是否通过标准版的operator new)释放内存。异常发生时(operator new成功调用,但调用对象构造函数时发生异常),编译器会调用与operator new参数对应的operator delete版本,若未找到,则不会调用其他形式的operator delete
  • operator new与new handler。编写自定义的operator new,在发生异常或内存不足时,应正确调用已设置的new handler

4. 自定义operator new与operator delete

  • 可以重新定义标准库提供的非placement版本的operator new和operator delete
  • 建议在global和class作用域中重写或重载自定义的operator new和operator delete

5. operator new/delete与类层次

  • 类的operator new成员通常仅负责当前类的内存分配,并不负责子类的内存非配
  • 类的析构函数应该是virtual的,否则Base *pb = new Derived; delete pb;将不能传递正确的size_t参数给子类的operator delete成员

6. operator new/delete与operator new[]/delete[]

  • 以上规则均适用于operator new[], operator delete[],仅仅是函数名字不同

参考:

C++中的new与delete总结的更多相关文章

  1. Oracle中的Truncate和Delete语句

    Oracle中的Truncate和Delete语句   首先讲一下,truncate命令:   语法:TRUNCATE  TABLE  table; 表格里的数据被清空,存储空间被释放. 运行后会自动 ...

  2. oracle 中删除表 drop delete truncate

    oracle 中删除表 drop delete truncate   相同点,使用drop delete truncate 都会删除表中的内容 drop table 表名 delete from 表名 ...

  3. Hibernate Session中的save(),update(),delete(),saveOrUpdate() 细粒度分析

    Hibernate在对资料库进行操作之前,必须先取得Session实例,相当于JDBC在对资料库操作之前,必须先取得Connection实例, Session是Hibernate操作的基础,它不是设计 ...

  4. C++中的new与delete

    C++中对象数组创建时,主要注意的点有:虚函数和带参数的构造函数,当出现虚函数时,对象数组中如通过父对象指向子对象,因为需要做Slice,析构时会造成指针错误引发内存泄露.测试程序如下: class ...

  5. sql server 中删除表中数据truncate和delete的区别(转载自.net学习网)

    我们都知道truncate table可以用来删除整个表的内容,它与delete后面不跟where条件的效果是一样.但除此之外,我们还清楚它们之间有其它的区别吗?本章我们将一起讨论truncate与d ...

  6. Javascript 中的 in, hasOwnProperty, delete, for/in

    in 运算符 判断对象是否拥有某一属性只要对象拥有该属性,就会返回true,否则false var point = { x:1, y:1 };alert( 'x' in point );  //tru ...

  7. 含有自增序列的表中使用truncate与delete的不同结果

    一个含有自增序列的表,使用delete跟truncate之后会有什么不同结果呢? 大概说一下,使用truncate,表中的记录全部被清除,如果向表中插入数据,那么数据的排序是从1开始的. 如果使用的是 ...

  8. ASP.NET MVC 学习8、Controller中的Detail和Delete方法

    参考:http://www.asp.net/mvc/tutorials/mvc-4/getting-started-with-aspnet-mvc4/examining-the-details-and ...

  9. SharePoint 2010中列表Add和Delete事件解析

    转:http://winsystem.ctocio.com.cn/26/11400026_2.shtml [IT专家网独家撰稿]SharePoint 2010与以前的版本相比,天翻地覆的变化并不为过. ...

随机推荐

  1. poj2478

    比较简单的树形dp; 定义s[i]为节点i的子树节点数和(包括自身):叶子节点s[j]=1; s[i]=signma(s[k])+1 (k是i的孩子) 则i满足的条件是 1.s[k]<=n di ...

  2. Dataguard Content

    1.Dataguard环境设计的三个重要概念 1.1 Primary数据库 在Data Guard的环境中与Standby数据库对应的数据库即是Primary数据库,也就是Primary数据库正在运行 ...

  3. Kettle定时执行(ETL工具)【转】

    1,Kettle跨平台使用.    例如:在AIX下(AIX是IBM商用UNIX操作系统,此处在LINUX/UNIX同样适用),运行Kettle的相关步骤如下:    1)进入到Kettle部署的路径 ...

  4. Apache Mina原理及典型例子分析

    Apache Mina ,一个高性能 Java 异步并发网络通讯框架.利用 Mina 可以高效地完成以下任务: TCP/IP 和 UDP/IP 通讯 串口通讯 VM 间的管道通讯 SSL/TLS JX ...

  5. 【转】ubuntu下自动挂载硬盘分区

    1, 首先摸清我系统的硬盘分区等使用情况 sudo fdisk -l Disk /dev/sda: 128.0 GB, 128035676160 bytes 255 heads, 63 sectors ...

  6. TPL

    namespace TPLTest { public partial class Form1 : Form { public Form1() { InitializeComponent(); } pr ...

  7. HDU4738 Caocao's Bridges 无向图的桥

    一眼题:找所有的桥,然后求最小权值 但是有很多坑点 1:如果本来不联通 输出0,(这个坑我知道) 2:但是还有一个坑,就是当整个连通,最小桥的权值是0时,也必须派一个人去,wa了无数遍(还是太年轻) ...

  8. 第一天CSS实战培训及笔记及感想

    首先,我很激动...... 3点了,凌晨3点了,我居然还没睡.总共不到3个小时的视频消化了6个小时,今天是培训班第一天,一下子就来高强度的讲课,整个上过基础班的都听得东倒西歪,更别说我这个没上基础班滴 ...

  9. C# 多线程 方法,类的标记

    [MethodImplAttribute(MethodImplOptions.Synchronized)] 此标记可用于方法,将一个方法标记为单线程进入,但在多个实例的时候仍有可能导致问题,比较有共享 ...

  10. 一些常被你忽略的CSS小知识

    1.CSS的color属性并非只能用于文本显示 对于CSS的color属性,相信所有Web开发人员都使用过.如果你并不是一个特别有经 验的程序员,我相信你未必知道color属性除了能用在文本显示,还可 ...