参考资料:

http://en.cppreference.com/w/cpp/memory/new/operator_new

http://en.cppreference.com/w/cpp/memory/new/operator_delete

http://www.wuzesheng.com/?p=840

http://www.blogjava.net/bacoo/archive/2008/07/13/214612.html

#include <cstdio>
#include <cstdlib>void * operator new(size_t unSize)
{printf("operator new called\n");return malloc(unSize);
}
void * operator new[](size_t unSize)
{printf("operator [] called\n");return malloc(unSize);
}void * operator new(size_t unSize, int nLine, const char * pFunc)
{printf("operator new called, line: %d, func: %s\n",nLine, pFunc);return malloc(unSize);
}
//注意:c++14才支持全局delete或delete【】有多个参数,参看参考资料2.下面两个delete不会覆盖全局的。
void operator delete(void * pMem,size_t unSize)
{printf("delete1: %u\n", unSize);free(pMem);
}
void operator delete[](void * pMem, size_t unSize)
{printf("delete[]: %u\n", unSize);free(pMem);}class A
{
public:A(int a = 0) :_a(a){   printf("constructor called\n");}  virtual ~A(){printf("~A()\n");}void * operator new(size_t unSize){printf(" calledA\n");return malloc(unSize);}
     //注意:但是支持自定义类型操作符new或delete重载支持size_t参数。即要删除对象的大小delete,要删除对象数组大小delete[].。void operator delete(void * pMem, size_t unSize){printf("delete2: %u\n", unSize);free(pMem);}void operator delete[](void * pMem, size_t unSize){printf("delete[]: %u\n", unSize);free(pMem);}private:int _a;
};class B: public A
{
public://隐式的为静态函数。void * operator new(size_t unSize, int nLine, const char * pFunc){printf("operator new called, line: %d, fileB: %s\n",nLine, pFunc);printf("operator new: %u\n", unSize);//_b=0;return malloc(unSize);}~B(){printf("~B()\n");}int _b;int _bb;
};int main()
{A * pA = new A(10);printf("#######\n");A * pB = new (__LINE__, __FILE__) B();printf("#######\n");A * szA = new A[10];B *szB = new B[10];printf("#######\n");delete pA; printf("#######\n");delete pB; printf("#######\n");delete [] szA;printf("#######\n");delete [] szB;printf("#######\n");
//下面两个不是自定义类,没有类重载new.delete故只能调用全局的,本程序全局不支持size_t参数,故只能调用标准C++中的全局operate delete.故不会打印信息。char * pC = new char[10];delete [] pC;
    char *pu = NULL;    delete pu;}

gcc下运行结果:

 calledA
constructor called
#######
operator new called,
operator new: 16
constructor called
#######
operator [] called
constructor called
constructor called
constructor called
constructor called
constructor called
constructor called
constructor called
constructor called
constructor called
constructor called
operator [] called
constructor called
constructor called
constructor called
constructor called
constructor called
constructor called
constructor called
constructor called
constructor called
constructor called
#######
~A()
delete2: 8
#######
~B()
~A()
delete2: 16
#######
~A()
~A()
~A()
~A()
~A()
~A()
~A()
~A()
~A()
~A()
delete[]: 84//注意84=4+8*10,数组分配的堆空间,第一个int空间放数组个数,接下来顺序放对象#######
~B()
~A()
~B()
~A()
~B()
~A()
~B()
~A()
~B()
~A()
~B()
~A()
~B()
~A()
~B()
~A()
~B()
~A()
~B()
~A()
delete[]: 164#######
operator [] called //调用覆盖的全局函数operate new [],打印信息。                    //delete[]调用全局的。

说明:1 在vs中类中delete[]的size_t是8和16.不同编译器结果不同。理论上应该是数组大小*类型字节。

2 如果基类有virtual析构函数,则传给operator delete的大小讲个怒被删除指针所指对象的动态类型而变化,如果没有声明为virtual,那么通过基类指针删除指向派生类对象,大小为基类大小。

总结:

1 malloc只是C函数,内部应该是使用类似deepalloc等,主要功能是分配原始内存,返回void*类型,需要显示转换为对应对象 类型指针。没有调用对象构造函数。C中函数本来就没有类没有构造函数。

free释放回收堆空间。

2 C++中的new 和delete是操作符,A * pA = new A(10)分别调用下面两步:

先调用void * operator new(size_t unSize) (调用顺序:那个有就调用那个:类中重载了就调用类的,然后全局重载,最后是C++源码中的全局函数)分配原始内存,未初始化的。里面可以调用malloc或者类似deapalloc来分配内存。

在调用A的构造函数,用初始化参数初始化。

delete pA;也分两步:

先调用A析构函数;

在调用void operator delete(void * pMem)(调用顺序同上面operator new),释放内存。可调用free实现或者其他实现。

3 operator new,operator delete隐式静态函数,写不写static都是静态的。

为什么必须是静态的呢?因为他们要么在构造对象前使用要么在析构后使用。属于类的函数,不是对象的函数。

4 operator new中传入的大小是怎么获得的呢,我觉得类似于sizeof(类型名)

关于sizeof不需要实例对象,我觉得类为实例化编译器不会给成员变量分配空间,但应该有个地方放的声明,标明变量类型等。

还有,sizeof大小不包括静态成员变量,静态变量一般放在静态区,不属于对象。没有成员变量的类大小为1,有虚函数就要多4个字节(虚函数表指针)。

最后小结一下,new 和delete都是内建的操作符,语言本身所固定了,无法重新定制。但它所调用的内存分配/释放的函数,即operator new和operator delete可以被重载

ps:

从汇编代码可看出:对单个堆对象调用delete和对堆对象数组调用delete[]可以发现,两种情况最主要的差别是在调用析构代理函数时传递的对象首地址,用delete析构单个对象是传进的堆空间首地址(也是堆对象首地址),而用delete[]析构对象数组时传递的是偏移堆空间首地址4byte处内存地址(即堆空间中第一个对象首地址,前四个字节是个int型,放的数组大小,即对象个数)。因此,在释放单个对象时调用delete[],或者释放对象数组时调用delete,都会造成错误,应该配对使用。

转载于:https://www.cnblogs.com/Yogurshine/p/3668249.html

C++ 操作符new和delete相关推荐

  1. C++中的new和delete操作符重载

    文章目录 1 new和delete操作符重载 1.1 new和delete操作符重载简介 1.2 静态存储区中创建动态对象 1.3 在指定的地址上创建C++对象 2 new[]和delete[]操作符 ...

  2. 浅谈Javascript中的void操作符

    由于JS表达式偏啰嗦,于是最近便开始采用Coffeescript来减轻负担.举个栗子,当我想取屋子里的第一条dog时,首先要判断house对象是否存在,然后再判断house.dogs是否存在,最后取h ...

  3. More Effective C++:理解new和delete

    转载自: http://dev.yesky.com/242/2585242.shtml 人们有时好像喜欢故意使C++语言的术语难以理解.比如说new操作符(new operator)和operator ...

  4. 《C++面向对象高效编程(第2版)》——3.4 赋值操作符

    本节书摘来自异步社区出版社<C++面向对象高效编程(第2版)>一书中的第3章,第3.4节,作者: [美]Kayshav Dattatri,更多章节内容可以访问云栖社区"异步社区& ...

  5. 从 +new Date 说起,Javascript的一元操作符

    http://zhouhua.github.io/2013/07/09/UnaryOperator/ 更多 在偶然打开d3 的源代码的时候,我看到了这样一段代码. 1 2 3 if (!Date.no ...

  6. C# new关键字和对象类型转换(双括号、is操作符、as操作符)

    一.new关键字 CLR要求所有的对象都通过new来创建,代码如下: Object obj=new Object(); 以下是new操作符做的事情 1.计算类型及其所有基类型(一直到System.Ob ...

  7. C++ 中 new 操作符内幕:new operator、operator new、placement new

    一.new 操作符(new operator) 人们有时好像喜欢有意使C++语言的术语难以理解.比方说new操作符(new operator)和operator new的差别. 当你写这种代码: st ...

  8. More Effective C++读书笔记(二)

    1.不要试图重载||,&&操作符,因为它们使用短路求值法(一旦确定了布尔表达式的真假值,即使还有部分表达式没有被测试,布尔表达式也停止运算),而重载之后采用的是函数调用法.首先当函数被 ...

  9. 第4章 类型基础 -- 4.1 所有类型都从System.Object派生

    4.1 所有类型都从System.Object派生 "运行时"要求每个类型最终都从System.Object类型派生. 由于所有类型最终都从System.Object派生,所以每个 ...

最新文章

  1. c语言combine函数,combine
  2. 使用Telnet与ssh协议远程登录linux系统
  3. c++ 缓存和缓冲_【嵌入式C】放弃printf,选择了精简snprintf
  4. 谷歌旗下Waymo开启数据集虚拟挑战赛
  5. 谈谈前端产品质量控制
  6. Java运算符——通过示例学习Java编程(6)
  7. 项目中的软件需求说明书的访谈部分
  8. LeetCode刷题——62. 不同路径
  9. 重拾数月前做的微信红包小项目
  10. 深入理解JVM—Java 6 JVM参数配置说明
  11. python selenium框架搭建_python + selenium 自动化框架搭建
  12. 海康摄像头故障处理踩坑记录
  13. 修改mac地址导致计算机无法上网,如何解决Win7计算机上无法修改MAC地址的问题...
  14. 【虹科科普】信号发生器分类及任意波形发生器原理
  15. 2017企业咨询服务公司排行榜
  16. JavaScript中的动画效果
  17. 新的3D地图制图技术改变了全球定位的游戏规则
  18. 5G技术—移动通信制式演进发展历程测试题目
  19. Thymeleaf select 实现默认选中,使用 th:field 字符串无效问题
  20. 如何设置VSCode删除整行快捷键?

热门文章

  1. python3能做什么_你都用 Python 来做什么?
  2. eq linux_《Linux设备驱动程序》(十二)——时间操作(一)
  3. org.json的使用详解
  4. 基于深度学习的驾驶行为预测方法
  5. one-hot与词袋模型
  6. uefi装原版win8.1怎么装|uefi gpt启动模式安装win8原版系统步骤
  7. OpenCv学习笔记(二)--Mat矩阵(图像容器)的创建及CV_8UC1,CV_8UC2等参数详解
  8. ffmpeg sws_scale函数详解
  9. Linux常用命令—权限管理命令—权限管理命令chmod
  10. ie系列浏览器_2020下半年河北教师资格准考证打印只能用ie浏览器吗