当前位置:主页 > c/c++教程 > C++ opeartor new和placement new

C++中的opeartor new和placement new使用步骤

发布:2023-03-04 14:00:01 59


给大家整理了相关的编程文章,网友晏高妍根据主题投稿了本篇教程内容,涉及到C++、opeartor、new、C++、placement、new、C++ opeartor new和placement new相关内容,已被322网友关注,下面的电子资料对本篇知识点有更加详尽的解释。

C++ opeartor new和placement new

new做了哪些:

在c++中,对new的调用时,new完成的工作通常是有以下几步:

调用operator new函数分配出内存待用对象的构造方法构造出对象返回该对象的指针

operator new
(1)只分配所要求的空间,不调用相关对象的构造函数。当无法满足所要求分配的空间时,则
->如果有new_handler,则调用new_handler,否则
->如果没要求不抛出异常(以nothrow参数表达),则执行bad_alloc异常,否则
->返回0
(2)可以被重载
(3)重载时,返回类型必须声明为void*
(4)重载时,第一个参数类型必须为表达要求分配空间的大小(字节),类型为size_t
(5)重载时,可以带其它参数

opeartor new重载测试

class X
{
public:
    X() { cout<<"constructor of X"<

那么为什么要重载operator new函数呢?首先第一点当然是因为new作为一种操作符是不能被重载的,而作为new中重要的一环:分配内存,重载operatir new就变的一种必要的操作了。全局opeartor new在分配内存时,实际上也是对malloc的一层包装,在进行大量次数的内存分配时容易出现内存碎片的问题,通过重载operator new函数可以自定的将内存分配在独立出来的一块内存区域,可以更高效率的实现内存分配的管理,同时也可以有效减少内存碎片化以及不易与管理的问题。

重载operator new函数还有很多的用途,比如,他可以帮助我们查找内存泄漏,在c++中,内存泄漏是痛中之痛,重载该函数并与宏定义相配合可以很好的检测出内存泄漏的地方在哪里。相关文章链接:https://www.xz577.com/article/41939.htm

placement new

placement new是operator new的一个重载版本,他的作用是可以将一个对象分配到指定的内存空间。实现代码如下:

void* operator new(std::size_t, void* __p) throw()
{
    return __p;
}

placement new 只是operator new的一个重载版本,只是起了一个别名而已.
代码示例:

class A{
    int num;
public:
    A(){
        cout<<"A's constructor"<

阅读以上程序,注意以下几点。
(1)用定位放置new操作,既可以在栈(stack)上生成对象,也可以在堆(heap)上生成对象。如本例就是在栈上生成一个对象。

(2)使用语句A* p=new (mem) A;定位生成对象时,指针p和数组名mem指向同一片存储区。所以,与其说定位放置new操作是申请空间,还不如说是利用已经请好的空间,真正的申请空间的工作是在此之前完成的。

(3)使用语句A *p=new (mem) A;定位生成对象是,会自动调用类A的构造函数,但是由于对象的空间不会自动释放(对象实际上是借用别人的空间),所以必须显示的调用类的析构函数,如本例中的p->~A()。

(4)万不得已才使用placement new,只有当你真的在意对象在内存中的特定位置时才使用它。例如,你的硬件有一个内存映像的I/O记时器设备,并且你想放置一个Clock对象在哪那个位置。

在一些高效率的程序中,往往会开辟出一块独立的内存空间配合placement new来实现高效率的内存释放与配置,如在SGI STL的内存配置函数allocate 与 deallcate函数,以及大名鼎鼎的memory pool技术都很大程度上依靠了placement new定位创建对象。在快速的内存分配与释放的过程中这是一个非常实用的方法。

Placement new使用步骤

在很多情况下,placement new的使用方法和其他普通的new有所不同。这里提供了它的使用步骤。

第一步 缓存提前分配

有三种方式:

1.为了保证通过placement new使用的缓存区的memory alignment(内存队列)正确准备,使用普通的new来分配它:在堆上进行分配

class Task ;
char * buff = new [sizeof(Task)]; //分配内存
(请注意auto或者static内存并非都正确地为每一个对象类型排列,所以,你将不能以placement new使用它们。)

2.在栈上进行分配

class Task ;
char buf[N*sizeof(Task)]; //分配内存

3.还有一种方式,就是直接通过地址来使用。(必须是有意义的地址)

void* buf = reinterpret_cast (0xF00F);

第二步:对象的分配

在刚才已分配的缓存区调用placement new来构造一个对象。

Task *ptask = new (buf) Task

第三步:使用

按照普通方式使用分配的对象:

ptask->memberfunction();
ptask-> member;
//...

第四步:对象的析构

一旦你使用完这个对象,你必须调用它的析构函数来毁灭它。按照下面的方式调用析构函数:

ptask->~Task(); //调用外在的析构函数,显式调用!

第五步:释放

你可以反复利用缓存并给它分配一个新的对象(重复步骤2,3,4)如果你不打算再次使用这个缓存,你可以象这样释放它:

delete [] buf;

总结:

(1)若想在堆上建立一个对象,应该用new操作符。它既分配内存又调用其构造函数进行初始化。
(2)若仅仅想分配内存,应该调用operator new(),他不会调用构造函数。若想定制自己在堆对象被建立时的内存分配过程,应该重写自己的operator new()。
(3)若想在一块已经获得的内存空间上建立一个对象,应该用placement new。在实际开发过程中,这种写法一般在高性能高稳定场景下使用。本文主要是为了更好的理解STL源码中alloator的内存管理行为所写。

理解可能并不规范,表达也会有所纰漏。

参考文章:

https://cloud.tencent.com/developer/article/1177460

https://blog.51cto.com/u_15060533/4689267

https://www.cnblogs.com/luxiaoxun/archive/2012/08/10/2631812.html

到此这篇关于C++中的opeartor new和placement new详解的文章就介绍到这了,更多相关C++ opeartor new和placement new内容请搜索码农之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持码农之家!


参考资料

相关文章

  • C++无痛实现日期类的示例代码

    发布:2023-03-04

    凡是要写类必须要提到六大默认成员(六位大爷):构造函数、析构函数、拷贝构造函数、赋值重载函数、取地址重载函数(包括const对象和普通对象);那么这次的日期类又需要伺候哪几位大爷呢?本文就来详细说说


  • 详解C++中动态内存管理和泛型编程

    发布:2023-03-05

    这篇文章主要为大家详细介绍了C++中动态内存管理和泛型编程的相关资料,文中示例代码讲解详细,对我们学习C++具有一定帮助,感兴趣的小伙伴快跟随小编一起学习一


  • C C++算法题解LeetCode1408数组中的字符串匹配

    发布:2023-03-04

    这篇文章主要为大家介绍了C C++算法题解LeetCode1408数组中的字符串匹配示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪


  • C++11新特性之右值引用与完美转发详解

    发布:2023-03-01

    C++11标准为C++引入右值引用语法的同时,还解决了一个短板,即使用简单的方式即可在函数模板中实现参数的完美转发。本文就来讲讲二者的应用,需要的可以参考一下


  • C/C++细数宏与函数有那些区别

    发布:2023-03-06

    在C程序中,可以用宏代码提高执行效率。宏代码本身不是函数,但使用起来象函数。预处理器用复制宏代码的方式代替函数调用,省去了参数压栈、生成汇编语言的CALL调用、返回参数、执行return等过程,从而提高了速度


  • C++实现数字转换为十六进制字符串的方法

    发布:2022-04-16

    这篇文章主要介绍了C++实现数字转换为十六进制字符串的方法,涉及C++操作数字与字符串转换的相关技巧,需要的朋友可以参考下


  • C++中的类成员函数当线程函数

    发布:2023-03-08

    这篇文章主要介绍了C++中的类成员函数当线程函数,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教


  • C++网络编程详细讲解

    发布:2023-03-08

    计算机是通过TCP/IP协议进行互联从而进行通信的,为了把复杂的TCP/IP协议隐藏起来,更方便的实现计算机中两个程序进行通信,引出了socket这个概念


网友讨论