zoukankan      html  css  js  c++  java
  • 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)个字节来存放对象的个数,或者说数组的大小。

  • 相关阅读:
    springCloud学习总览
    leetcode Q46.把数字翻译成字符串
    手把手教你用redis实现一个简单的mq消息队列(java)
    主流排序算法全面解析
    从零开始react实战:云书签(总览)
    从零开始react实战:云书签-1 react环境搭建
    springboot整合elasticsearch7.2(基于官方high level client)
    你知道如何在小程序中推送模板消息?
    最新ubuntu搭建公网个人邮件服务器(基于postfix,dovecot,mysql)
    手把手docker部署java应用(初级篇)
  • 原文地址:https://www.cnblogs.com/gtarcoder/p/4808837.html
Copyright © 2011-2022 走看看