Placement New
placement new是重载operator new的一个标准、全局的版本,它不能被自定义的版本代替(不像普通的operator new和operator delete能够被替换成用户自定义的版本)。
它的原型如下:
void *operator new( size_t, void *p )throw() { return p; }
使用形式:
new(place_address) type;
new (place_address) type (initialize_list);
首先我们区分下几个容易混淆的关键词:new、operator new、placement new
new和delete操作符我们应该都用过,它们是对堆中的内存进行申请和释放,而这两个都是不能被重载的。要实现不同的内存分配行为,需要重载operator new,而不是new和delete。
看如下代码:
class MyClass {…};
MyClass * p=new MyClass;
这里的new实际上是执行如下3个过程:
1调用operator new分配内存;
2调用构造函数生成类对象;
3返回相应指针。
delete p;
这里的delete实际上是执行如下2个过程
1调用析构函数析构类对象
2调用operator delete释放内存
operator new就像operator+一样,是可以重载的,但是不能在全局对原型为void operator new(size_t size)这个原型进行重载,一般只能在类中进行重载。如果类中没有重载operator new,那么调用的就是全局的::operator new来完成堆的分配。同理,operator new[]、operator delete、operator delete[]也是可以重载的,一般你重载了其中一个,那么最好把其余三个都重载一遍。
placement new是operator new的一个重载版本,只是我们很少用到它。如果你想在已经分配的内存中创建一个对象,使用new是不行的。也就是说placement new允许你在一个已经分配好的内存中(栈或堆中)构造一个新的对象。原型中void*p实际上就是指向一个已经分配好的内存缓冲区的的首地址。
我们知道使用new操作符分配内存需要在堆中查找足够大的剩余空间,这个操作速度是很慢的,而且有可能出现无法分配内存的异常(空间不够)。placement new就可以解决这个问题。我们构造对象都是在一个预先准备好了的内存缓冲区中进行,不需要查找内存,内存分配的时间是常数;而且不会出现在程序运行中途出现内存不足的异常。所以,placement new非常适合那些对时间要求比较高,长时间运行不希望被打断的应用程序。
使用方法如下:
1. 缓冲区提前分配
可以使用堆的空间,也可以使用栈的空间,所以分配方式有如下两种:
class MyClass {…};
void *p=operator new(sizeof(MyClass));或者char buf[sizeof(MyClass) ]; p=buf;
2. 对象的构造
MyClass * pClass=new(p) MyClass;
3. 对象的销毁
一旦这个对象使用完毕,你必须显式的调用类的析构函数进行销毁对象。但此时内存空间不会被释放,以便其他的对象的构造。
pClass->~MyClass();
4. 内存的释放
如果缓冲区在堆中,那么调用operator delete(p);进行内存的释放;如果在栈中,那么在其作用域内有效,跳出作用域,内存自动释放。
注意:
1) 在C++标准中,对于placement operator new []有如下的说明: placement operator new[] needs implementation-defined amount of additional storage tosave a size of array. 所以我们必须申请比原始对象大小多出sizeof(int)个字节来存放对象的个数,或者说数组的大小。
2) 使用方法第二步中的new才是placement new,其实是没有申请内存的,只是调用了构造函数,返回一个指向已经分配好的内存的一个指针,所以对象销毁的时候不需要调用delete释放空间,但必须调用析构函数销毁对象。
placement operator new[] 的例子:
#include <iostream>
#include <cstdio>
using namespace std;
class Point
{
public:
Point()
{
cout<<"Point"<<endl;
}
~Point(){cout<<"~Count"<<endl;}
private:
int a;
};
int main()
{
char* buf=new char[3*sizeof(Point)+sizeof(int)];
Point *p=new(buf)Point[3]; //placement operator new[]
for(int i=0; i!=3;++i)
{
p[i].~Point();
}
delete[] buf;
return 0;
}
Placement New相关推荐
- Complex Instance Placement
转自: https://specs.openstack.org/openstack/openstack-user-stories/user-stories/proposed/complex-insta ...
- Placement new
new 操作一般可以分为两个过程:1为申请内存空间 2为调用类型的构造函数进行构造 placement new 调用类型的构造函数对已存在的内存进行构造 1 #include<new.h> ...
- 二分图最大匹配(匈牙利算法) POJ 3020 Antenna Placement
题目传送门 1 /* 2 题意:*的点占据后能顺带占据四个方向的一个*,问最少要占据多少个 3 匈牙利算法:按坐标奇偶性把*分为两个集合,那么除了匹配的其中一方是顺带占据外,其他都要占据 4 */ 5 ...
- OpenStack Placement Project(Rocky to Train)
目录 文章目录 目录 前言 背景 Placement 基本概念 数据模型 指令行 Placement Web Application 的实现与分析 Placement 在 Nova 中的应用 Get ...
- OpenStack Nova Placement API 统一资源管理接口的未来
目录 目录 Placement API 为何称之为 "未来" 操作对象基本概念 数据库操作样例 Placement API 在创建虚拟机时的调度过程 Placement REST ...
- Placement new的用法及用途
什么是placement new? 所谓placement new就是在用户指定的内存位置上构建新的对象,这个构建过程不需要额外分配内存,只需要调用对象的构造函数即可. 举例来说: class foo ...
- pymysql安装_openstack stein安装placement
openstack stein install placement 安装组件: placement 注:安装服务均遵循以下步骤: mariadb创库授权 keystone创建角色并关联 keyston ...
- CNCF 沙箱项目 OCM Placement 多集群调度指南
作者: 邱见|红帽资深软件工程师,Open Cluster Management (OCM) 社区发起人,负责人 郝青|红帽高级软件工程师,Open Cluster Management (OC ...
- placement new(转)
今天看STL源码遇到一个问题: template <class _T1, class _T2> inline void _Construct(_T1* __p, const _T2& ...
- placement new 操作符
placement new操作符能够在分配内存时指定内存位置.下面的程序使用了placement new操作符和常规new操作符给对象分配内存. // placenew.cpp -- new, pla ...
最新文章
- Exchange 分析器工具介绍及案例分析
- php程序应用实例,PHP教程.应用实例1_php
- 大唐波斯将军 机器人_参观长沙博物馆“粟特人在大唐”文物展,感叹多元文明的交融互鉴...
- Yii资源包加载JS/CSS
- 重新初始化k8s master节点
- GBDT和随机森林的区别
- Hello JAVA World!
- 网络安全实验室 脚本关 解析
- dnf自动刷图python_dnf卡盟_【python接口自动化】- openpyxl读取excel数据
- ibm主机安装服务器系统安装系统安装系统安装方法,IBM系列服务器安装操作系统安装方法.ppt...
- HTML基本知识学习 2021-04-08
- 接触【专利写作】的必备知识(包含少部分撰写技巧)
- Excel学习笔记1||求和函数SUM、SUMIF、SUMIFS、SUMPRODUCT
- WINCE下模拟鼠标点击,移动
- CC2640R2F BLE5.0 CC2640R2F软件架构
- 均值方差模型python_python实现资产配置(2)--Blacklitterman 模型
- 关于手持设备PDA的开发
- 根据汉字,获取拼音首字母(转)
- 动态库链接boost静态库
- Google还能做什么?(转贴)