一、定义

1、new

new是c++中的关键字,,其行为总是一致的。它先调用operator new分配内存,然后调用构造函数初始化那段内存。

new 操作符的执行过程:
1. 调用operator new分配内存 ;
2. 调用构造函数在operator new返回的内存地址处生成类对象;

2、operator new

operator new是一个函数,就像重载任何一个符号如operator +,它用来分配内存(只不过new除了调用它还有其他步骤)。它可以被重载,通过重载它,可以改变new操作符的功能。它的功能介意类比c语言中的malloc,如果类中没有重载operator new,那么调用的就是全局的::operator new来从堆中分配内存。

2、placement new

placement new 是c++中对operator new 的一个标准、全局的重载版本。它并不分配内存,只是返回指向已经分配好的某段内存的一个指针,placement new允许你在一个已经分配好的内存中(栈或者堆中)构造一个新的对象。

二、使用方法

1、new的使用

在堆上分配分配一块内存

struct A* i0 = new A;
struct A* i1 = new A();

看new的原型:

void* operator new(std::size_t) _GLIBCXX_THROW (std::bad_alloc)__attribute__((__externally_visible__));
void* operator new[](std::size_t) _GLIBCXX_THROW (std::bad_alloc)__attribute__((__externally_visible__));
void operator delete(void*) _GLIBCXX_USE_NOEXCEPT__attribute__((__externally_visible__));
void operator delete[](void*) _GLIBCXX_USE_NOEXCEPT__attribute__((__externally_visible__));
void* operator new(std::size_t, const std::nothrow_t&) _GLIBCXX_USE_NOEXCEPT__attribute__((__externally_visible__));
void* operator new[](std::size_t, const std::nothrow_t&) _GLIBCXX_USE_NOEXCEPT__attribute__((__externally_visible__));
void operator delete(void*, const std::nothrow_t&) _GLIBCXX_USE_NOEXCEPT__attribute__((__externally_visible__));
void operator delete[](void*, const std::nothrow_t&) _GLIBCXX_USE_NOEXCEPT__attribute__((__externally_visible__));

发现它有一个参数,size_t,表示前面调用placement new分配的内存大小,new接下来会在这块内存中调用构造函数,new的操作也是c++来保证的。

2、operator new的使用

分配8个字节的内存,因为是未重载,所以这里调用的是全局operator new,从堆上分配了8个字节

void* i = operator new (8);

如果想重载operator new需要注意以下几点:

(1)重载时,返回类型必须声明为void*

(2)重载时,第一个参数类型必须为表达要求分配空间的大小(字节),类型为size_t

(3)重载时,可以带其它参数

(4)分配函数为类成员函数或全局函数;如果分配函数在全局范围之外的名称空间范围中声明,或者在全局范围中声明为静态,则程序是病态的

比如下面的例子中,在A重载了operator new打印出tag,返回全局的opereator new,然后在main函数中调用A的重载版本。

struct A{int a;char b;void* operator new(size_t size,int tag) throw(){cout << tag << endl;return ::operator new(size);}
};int main()
{void* i = A::operator new (8,1);cout << i << endl;return 0;
}

最终结果即分配了内存,又打印出了tag的值

如果我们重载全局的operator new函数,然后调用new,则new的操作也会被更改,比如下面的例子(这个例子的operator new只有一个参数)

struct A{int a;char b;
};void* operator new(size_t num) throw(){cout << num << endl;return nullptr;
}int main()
{A* i = new A;cout << i << endl;return 0;
}

最终的结果是

可以看出,虽然没有直接调用operator new,但是new的操作已经被更改了。

还需要关注一个小地方,就是operator new调用时的参数和new的参数是有所区别的。new在调用的时候会忽略第一个size_t的参数,但是如果直接调用operator new来进行内存分配的时候是需要这个参数的。

也就是本节的第二个例子如果operator new的定义要像本节的第一个例子有两个参数的话,对new的调用应该如下:

A* i = new(1) A ;

3、placement new的使用

placement new是c++实现的operator new版本,它的实现如下

// Default placement versions of operator new.
inline void* operator new(std::size_t, void* __p) _GLIBCXX_USE_NOEXCEPT
{ return __p; }
inline void* operator new[](std::size_t, void* __p) _GLIBCXX_USE_NOEXCEPT
{ return __p; }// Default placement versions of operator delete.
inline void operator delete  (void*, void*) _GLIBCXX_USE_NOEXCEPT { }
inline void operator delete[](void*, void*) _GLIBCXX_USE_NOEXCEPT { }
//@}

可以看到实际上它就返回了传进来的地址,根据operator的第二个例子,通过重载全局的operator new之后,new函数的操作就被改变了。也就能猜出,在调用new的时候参数需要加上一个地址,placement new的功能就是在这个地址之上进行构造。

placement new的使用步骤如下

1)分配内存

char* buff = new char[ sizeof(Foo) * N ];
memset( buff, 0, sizeof(Foo)*N );

2)构建对象

Foo* pfoo = new (buff)Foo;

3)使用对象

pfoo->print();
pfoo->set_f(1.0f);
pfoo->get_f();

4)析构对象,显式的调用类的析构函数。

pfoo->~Foo();

5)销毁内存

delete [] buff;

上面5个步骤是标准的placement new的使用方法。

转载于:https://www.cnblogs.com/likaiming/p/9393083.html

c++中的new、operator new、placement new相关推荐

  1. c++ new, operator new, placement new

    c++ new 用于动态分配内存.比如 A* a=new A():其实这里一共有三步: 1.分配sizeof(A)的内存,这里的分配是通过operator new(std::size_t)实现的 2. ...

  2. C++中的opeartor new和placement new详解

    博客:https://goodfanqie.github.io(文章优先展示地方,推荐在此阅读.) new做了哪些: 在c++中,对new的调用时,new完成的工作通常是有以下几步: 调用operat ...

  3. 关于python3中的包operator(支持函数式编程的包)

    文章目录 1.functools 2.operator.itemgetter 3.operator.attrgetter 虽然 Guido 明确表明,Python 的目标不是变成函数式编程语言,但是得 ...

  4. C++中的定位放置new(placement new)

    转载:https://www.cnblogs.com/weekbo/p/8533368.html 今天在使用new时,需要使用特定位置的一块内存,因此查了资料,发现该文章有帮助就现转载做一个备份. 一 ...

  5. C++中的new、operator new与placement new

     C++中的new/delete与operator new/operator delete new operator/delete operator就是new和delete操作符,而operato ...

  6. C++中placement new操作符(经典)

    placement new是重载operator new的一个标准.全局的版本,它不能被自定义的版本代替(不像普通的operator new和operator delete能够被替换成用户自定义的版本 ...

  7. C++ new/new operator、operator new、placement new初识

    简要释义 1.operator new是内存分配函数(同malloc),C++在全局作用域(global scope)内提供了3份默认的operator new实现,并且用户可以重载operator ...

  8. operator new与placement new

    通常讲的new指的是new operator,使用new operator的时候,实际上执行了三个步骤: 1)调用operator new分配内存 :2)调用构造函数生成类对象:3)返回相应指针. 分 ...

  9. 内核功能导致重启_诊断修复 TiDB Operator 在 K8s 测试中遇到的 Linux 内核问题

    Kubernetes(K8s)是一个开源容器编排系统,可自动执行应用程序部署.扩展和管理.它是云原生世界的操作系统. K8s 或操作系统中的任何缺陷都可能使用户进程存在风险.作为 PingCAP EE ...

最新文章

  1. 主流WEB开发语言简单对比(转)
  2. 神策数据入选 Facebook 全球合作计划,助力出海客户拥抱全球化广告生态
  3. Fragment onCreateView inflate注意事项 (整理)
  4. object 'libproxychains.so.3' from LD_PRELOAD cannot be preloaded
  5. 如何使用阿里云ARMS轻松重现用户浏览器问题
  6. UPS不间断电源的种类有哪些 常见的3类UPS电源
  7. matlab 柱状图_MATLAB作图实例:24:条形图
  8. java语言的数据类型_Java语言的数据类型
  9. java doc书写_apidoc利用代码注释书写文档
  10. 【蓝桥杯单片机(18)】第七届省赛-模拟风控制系统
  11. 安卓ttf格式的字体包_字体 | 新游黑体(游)精巧的日系字体~
  12. Handler消息机制详解,另对于MessageQueue阻塞线程的详解
  13. 学校考场重要组成部分ntp子母钟(时间同步系统)方案
  14. 微信公众号开发:实人认证,活体人脸识别解决方案
  15. 联想台式机快捷键(F1~F12)取消按Fn,设置为标准功能键
  16. 50多款Android运用法式遭Rootkit病毒侵扰进犯
  17. 家用台式计算机硬件配置清单,台式电脑组装配置清单
  18. HTML期末学生大作业-新闻网页作业html+css
  19. 电路邱关源学习笔记——1.5电压源和电流源
  20. 小程聊微服务--微服务思想

热门文章

  1. 揭开知识库问答KB-QA的面纱2·语义解析篇
  2. android的窗口机制分析------UI管理系统
  3. Sparkmllib scala线性回归
  4. 【问链-区块链基础知识系列】 第十四课 数字货币交易所的前世、今生和未来(一)
  5. 以太坊代币标准: ERC20、ERC223的介绍与比较
  6. android 自定义banner,Android项目 引入Banner开源库(轮播图)
  7. linux连接到程序,Linux下C程序的链接过程
  8. 百度超级搜索技巧集锦
  9. Ubuntu16.04下CUDA 9.0 + cuDNN v7.0 + tensorflow 1.6.0(GPU)环境搭建
  10. Codeforces 516D Drazil and Morning Exercise (栈、二分)