c++中new/operator new/placement new
1. new/delete
c++中的new(和对应的delete)是对堆内存进行申请和释放,且两个都不能被重载。
2. operator new/operator delete
c++中如果想要实现不同的内存分配行为,需要重载operator new,operator delete。operator new和operator +一样是可以重载的,但是不能在全局对原型为 void* operator new(size_t size)这个原型进行重载,一般只能在类中进行重载(operator new)。同理,operator new[], operator delete, operator delete[]也是可以重载的,一般在重载了其中一个之后,最好将其他三个都重载一遍。
class MyClass{
....
};
MyClass* p = new MyClass;
这里的new实际执行三个过程:
(1)调用operator new分配内存
(2)调用构造函数构造类对象
(3)返回指针
在类中可以对operator new进行重载,如果类中没有重载operator new,则在new一个对象的时候,调用的是全局的::operator new来完成堆的分配。
3. placement new
placement new 是operator new的一个重载版本,placement new允许在一个已经分配好的内存块(堆或者栈)中创建一个对象。原型中void*p实际指向一个已经分配好的内存缓冲区的首地址。
new操作符分配内存需要在堆中查找足够大的剩余空间,这个操作速度很慢,而且有可能出现无法分配内存的异常。placement new构造对象都是在一个预先准备好的内存缓冲区中进行,不需要查找内存,内存分配的时间为常数;而且不会出现在程序运行中途出现内存不足的异常。所以,placement new适合那些对时间要求比较高,长时间运行不希望被打断的应用程序。
placement new的使用方法:
(1)缓冲区提前分配
可以使用堆空间,也可以使用栈空间。
class MyClass{
...
};
char* buf = new char[N*sizeof(MyClass) + sizeof(int)];
或者
char buf[N*sizeof(MyClass) + sizeof(int)];
(2)对象的构造
MyClass* pClass = new (buf) MyClass; //placement new
(3)对象的销毁
一旦对象使用完毕,必须显式的调用析构函数来销毁对象。但此时内存空间不会被释放,以便其他对象的构造。
pClass->~MyClass(); //显式调用析构
(4)内存的释放
如果缓冲区在堆中,则调用delete[] buf进行释放;如果在栈中,当跳出作用域之后,内存自动释放。
虽然内置类型没有构造函数,但也可以使用placement new
int* i = (int*)malloc(sizeof(int));
new (i) int();
注意
在C++标准中,对于placement operator new []有如下的说明: placement operator new[] needs implementation-defined amount of additional storage to save a size of array. 所以我们必须申请比原始对象大小多出sizeof(int)个字节来存放对象的个数,或者说数组的大小。
c++中new/operator new/placement new的更多相关文章
- C++内存管理(new operator/operator new/operator delete/placement new)
new operator 我们平时使用的new是new操作符(new operator),就像sizeof一样是语言内置的,不能改变它的含义,功能也是一样的 比如: string *ps = new ...
- Python中使用operator模块实现对象的多级排序
Python中使用operator模块实现对象的多级排序 今天碰到一个小的排序问题,需要按嵌套对象的多个属性来排序,于是发现了Python里的operator模块和sorted函数组合可以实现这个功能 ...
- 【转】C++易混知识点3. New Operator, Operator New, Placement New 实例分析,比较区别
我们知道,C++中引入了New 这个内置符号,很大方便了指针的使用,程序员不必关注与这块堆上新分配的内存是如何来的,如何初始化的,然后如何转换为我们想要的类型指针的.现在,我们重点来分析下这个NEW内 ...
- 关于python中的operator.itemgetter()函数的用法
1. operator.itemgetter(num)函数 表示对对象的第num维数据进行操作获取. >>>import operator >>>a = [1, 2 ...
- C++中的::operator new, ::operator delete
一般在使用new 和 delete的时候,做了两件事情,一是空间的配置( new 是分配,delete是回收),而是调用对象的析构函数 但是也有办法将这两个过程分开 那就是显式的调用::operat ...
- python中的operator.itemgetter函数
operator.itemgetter函数operator模块提供的itemgetter函数用于获取对象的哪些维的数据,参数为一些序号.看下面的例子 a = [,,] >>> b=) ...
- c++中的new、operator new、placement new
一.定义 1.new new是c++中的关键字,,其行为总是一致的.它先调用operator new分配内存,然后调用构造函数初始化那段内存. new 操作符的执行过程:1. 调用operator n ...
- C++中的new、operator new与placement new
转:http://www.cnblogs.com/luxiaoxun/archive/2012/08/10/2631812.html new/delete与operator new/operator ...
- C++中的new,operator new与placement new
以下是C++中的new,operator new与placement new进行了详细的说明介绍,需要的朋友可以过来参考下 new operator/delete operator就是new和 ...
随机推荐
- 【C#/WPF】TextBlock/TextBox/Label编辑文字的问题
标题有点描述不清,就当是为了方便自己用时易于搜索到. 总之需求是:显示用户信息(文字)时,允许用户编辑自己的信息. 效果图如下: 点击[编辑]按钮前: 点击[编辑]按钮后,允许编辑: 别吐槽为甚性别还 ...
- sqlserver日期函数<转>
一.sql server日期时间函数Sql Server中的日期与时间函数 1. 当前系统日期.时间 select getdate() 2. dateadd 在向指定日期加上一段时间的基 ...
- 配置TOMCAT 修改默认ROOT路径
本文转载http://xxs673076773.iteye.com/blog/1134805 最合适的) 最直接的办法是,删掉tomcat下原有Root文件夹,将自己的项目更名为Root. 我在$to ...
- 【Hibernate步步为营】--核心对象+持久对象全析(二)
上篇文章讨论了Hibernate的核心对象,在开发过程中经经常使用到的有JTA.SessionFactory.Session.JDBC,当中SessionFactory可以看做数据库的镜像,使用它可以 ...
- rails中path、url路径解析,routes信息,form_for剖析,link_to示例,路由实例说明
原创,转载请注明http://www.cnblogs.com/juandx/p/3963023.html rails中path.url路径解析,routes信息,form_for剖析,link_to ...
- 在Linux环境下mysql的root密码忘记解决方法
MySQL密码的恢复方法之一 .首先确认服务器出于安全的状态,也就是没有人能够任意地连接MySQL数据库. 因为在重新设置MySQL的root密码的期间,MySQL数据库完全出于没有密码保护的 状态下 ...
- 如果通过html 链接打开app
https://my.oschina.net/liucundong/blog/354029 <!doctype html> <html> <head> <me ...
- variable `xxx' has initializer but incomplete type
错误:variable `xxx' has initializer but incomplete type 原因:xxx对应的类型没有找到,只把xxx声明了但是没给出定义.编译器无从确认你调用的构造函 ...
- 关于Cocos2d-x很多奇怪的报错
1.说什么找不到类和命名空间,但是已经包含头文件 项目-属性-配置属性-C/C++-附加包含目录-编辑-添加新行-写上$(EngineRoot) 2.很多语句报错,但是都没问题 我是这样理解的,书上的 ...
- C Language Study - 函数指针的使用
函数指针的使用 1.函数指针定义 第一次使用函数指针,我是这样声明的,typedef void ( *pSimulatepks )( uint8 *prxBuf, uint8 *prxBufLen ) ...