zoukankan      html  css  js  c++  java
  • 【C++】不同含义new和delete

    C++中存在着三种类型的与内存管理相关的接口,new 操作符(new operator),new 操作(operator new)和placement new.

    下面简单介绍这三种接口区别和联系.

    new操作符是语言内置的操作符,像sizeof一样,我们不能改变它的含义和功能.我们用new操作完成动态对象的创建.它主要完成两部分工作:

    1.分配足够的内存以便容纳所需类型的对象.

    2.调用构造函数初始化内存中的对象.

    new操作符分配内存时,需要调用一个内存分配函数完成内存分配的工作.这个函数就是new操作(operator new).

    函数operator new的声明方式如下:

    1 void* operator new(size_t size);

    我们定制new和delete主要就是指重写或重载这个函数来改变它的行为.

    有时候operator new并不完成我们的工作,例如我们要记录分配信息,我们要在已有的共享内存上创建对象等.这时候,我们就需要placement new.

    如果operator new接受的参数除了一定会的那个size_t之外还有其他,则这个operator new可称谓placement new

    在众多placement new版本中特别有用的一个是"接受一个指针指向对象该被构造之处",声明如下:

    1 void* operator new(std::size_t,void* pMemory) throw();

      总体而言,如果想在堆上建立一个对象,应该用new操作符.它既分配内存又为对象调用构造函数.如果仅仅想分配内存,就应该调用operator new函数,它不会调用构造函数.如果想定制自己的在堆对象被建立时的内存分配过程,就应该写自己的operator new函数,然后使用new操作符,new操作符会调用定制的operator new.如果想在一块已经获得指针的内存里建立一个对象,应该用placement new.

    内存释放的接口,delete操作,delete操作符和placement delete之间的区别与联系,与分配接口是类似的.

    我们在使用内存管理接口和定制new和delete时,要注意两个问题:

    1.内存分配和内存释放的接口是配套的.我们写了自己的placement new时,就一定要写具有相同额外参数的placement delete.

    2.在定制自己的内存管理接口时,要避免对标准形式的遮掩问题.因为可能会调用标准形式的版本来完成定制的专属版本.

     1 class StandardNewDeleteForms{
     2     static void* operator new(std::size_t size) throw(std::bad_alloc)
     3     {
     4         return ::operator new(size);
     5     }
     6     static void operator delete(void* pMemory) throw()
     7     {
     8         ::operator delete(pMemory);
     9     }
    10     static void* operator new(std::size_t size,void* ptr) throw()
    11     {
    12         return ::operator new(size,ptr);
    13     }
    14     static void operator delete(void* pMemory,void* ptr) throw()
    15     {
    16         ::operator delete(pMemory,ptr);
    17     }
    18     static void* operator new(std::size_t,const std::nothrow_t& nt) throw()
    19     {
    20         return ::operator new(size,nt);
    21     }
    22     static void* operator delete(void *pMemory,const std::nothrow_t&) throw()
    23     {
    24         ::operator delete(pMemory);
    25     }
    26 };
    27 
    28 class Widget:public StandardNewDeleteForms {
    29 public:
    30     using StandardNewDeleteForms::operator new;
    31     using StandardNewDeleteForms::operator delete;
    32     
    33     static void* operator new(std::size_t size,std::ostream& logStream) throw(std::bad_alloc);
    34     static void operator delete(void* pMemory,std::ostream& logStream) throw();
    35     ...
    36 };
  • 相关阅读:
    (转)simple-framework(MaliSDK框架分析)
    (转)libhybris及EGL Platform-在Glibc生态中重用Android的驱动
    (原)在firefly_rk3288开发板上解决openGL在设置32位色深以后出现花屏的问题
    参考论坛:Mali kernel driver TX011-SW-99002-r5p1-00rel0 for firefly
    (转)android媒体--stagefright概述【一】
    (转)android系统架构及源码目录结构
    (原)linux下利用cmake来编译jthread开源库
    (原)U盘可见容量不能被识别的处理方法
    学会阅读Java字节码
    JVM
  • 原文地址:https://www.cnblogs.com/dwdxdy/p/2613870.html
Copyright © 2011-2022 走看看