• 【转】C++易混知识点3. New Operator, Operator New, Placement New 实例分析,比较区别


    我们知道,C++中引入了New 这个内置符号,很大方便了指针的使用,程序员不必关注与这块堆上新分配的内存是如何来的,如何初始化的,然后如何转换为我们想要的类型指针的。现在,我们重点来分析下这个NEW内置符号背后的步骤和所调用到的函数。这里面涉及到new operator, operator new, placement new.


    转载请注明出处: http://blog.csdn.net/elfprincexu


    1. New Operator (__type__ * a = new a();)

    C 语言当中,我们在新申请一块内存的时候,通常使用的是malloc, 通常通过malloc(size_t size)来获得一块未初始化的raw memory。然后一般情况下我们会对该部分空间初始化(memset or memcpy)。

    C++语言引入了new 操作符,极大地方便了使用,它一下子把C语言中的好几个步骤一下完成了,让我们觉得神奇的是,不必去深究其中的调用。

    其实,new operator主要做了以下三个步骤的:

    std::string* str = new std::string("memory management");// 例如,我们想申请一个新的string空间,其中空间并被初始化为“memory management”,并且该空间由一个stringlei类型的指针来指向,并把它返回给str。


    1. 第一步,调用了 operator new 函数, operator new函数的作用 仅仅 是申请一块未被初始化的内存。

    函数申明为:void* operator new (size_t size)

    void* memory = operator new (sizeof("memory management"));// 申请足够大小的内存空间

    2. 第二部,调用string 构造函数,在该未初始化的空间上初始化,也就是“memory management”

    call string::string("memory management") on memory*

    3. 第三部,将该指针转换为指定的想要的指针类型

    string* str =  static_cast<std::string*> (memory);


      总结下来: 

    (1)通过operator new申请内存

    (2)使用placement new调用构造函数(简单类型忽略此步)

    (3)返回内存指针


    2. operator new (该函数仅仅 申请足够大小的内存,可以被重载)

    void * operator new (size_t size);

    举个例子来讲:

     1 // operator new example  
     2 #include <iostream>  
     3 #include <new>  
     4 using namespace std;  
     5    
     6 struct myclass {myclass() {cout <<"myclass constructed ";}};  
     7    
     8 int main () {  
     9    
    10    int * p1 = new int;  
    11 // same as:  
    12 // int * p1 = (int*) operator new (sizeof(int));  
    13    
    14    int * p2 = new (nothrow)int;  
    15 // same as:  
    16 // int * p2 = (int*) operator new (sizeof(int),nothrow);  
    17    
    18    myclass * p3 = (myclass*) operator new (sizeof(myclass));  
    19 // (!) not the same as:  
    20 // myclass * p3 = new myclass;  
    21 // (constructor not called by function call, even for non-POD types)  
    22    
    23    new (p3) myclass;   // calls constructor  
    24 // same as:  
    25 // operator new (sizeof(myclass),p3)  
    26    
    27    return 0;  

    28 }   

    重载operator new,

    void * operator new (size_t size, string str);// 比如我们添加一个形参string, 用来辅助输出

    调用

    Base *b = new (“Operator new overload example”) Base;// str 形参放在new 后的挂号里面,

    same as :

    Base *b = (Base* ) ( operator new (sizeof(Base), "Operator new overload example") );

    [cpp] view plaincopyprint?在CODE上查看代码片派生到我的代码片
    class Base {  
    public:  
      Base() { }  
       
      void *operatornew(size_t size, string str ) {  
        cout << "Logging an allocation of " << size << " bytes for new object'" << str << "'" << endl;  
        return malloc( size );  
      }  
       
      int var;  
      double var2;  
    };  
       
       

    Base* b = new ("Base instance 1") Base;   

    输出: Logging an allocation of 12 bytes for new object 'Base instance 1'


    3. Placement new. void* operator new ( size_t size, void* ptr) ;// ptr 会被返回,因为我们已经指定在已知的内存上

    归根结底来讲,placement new 是operator new 的一种特殊重载,它不分配内存,只是调用合适的构造函数在ptr所指的地方构造一个对象,之后返回实参指针ptr。

    例如:

    myclass* p3 = static_cast<myclass*> ( operator new (sizeof(myclass));// p3 已经指定一块足够放下myclass对象的空间,该空间未初始化,

    new (p3) myclass;// placement new, 在指定的p3空间上,call constructor myclass()来初始化该空间,并且返回p3.

      1 // operator new example  

     2 #include <iostream>  
     3 #include <new>  
     4 using namespace std;  
     5    
     6 struct myclass {myclass() {cout <<"myclass constructed ";}};  
     7    
     8 int main () {  
     9    myclass * p3 = (myclass*) operator new (sizeof(myclass));  
    10 // (!) not the same as:  
    11 // myclass * p3 = new myclass;  
    12 // (constructor not called by function call, even for non-POD types)  
    13    
    14    new (p3) myclass;   // calls constructor  
    15 // same as:  
    16 // operator new (sizeof(myclass),p3)  
    17    
    18    return 0;  
    19 }  
  • 相关阅读:
    angular.js 头部默认值,不使用json提交数据
    D1-FFmpeg拼接视频
    B23-Carthage的使用
    B22-SVN在iOS开发的使用中遇到的问题
    C4-Cordova在iOS平台的使用
    C2-PhoneGap的环境搭建及iOS项目创建
    C0-PhoneGap之移动开发策略的选择(翻译)
    C1-PhoneGap和Cordova的关系和认识
    B21-iOS 开发的一些tips(下)
    B17-禅与 Objective-C 编程艺术的阅读笔记
  • 原文地址:https://www.cnblogs.com/xiongyunqi/p/4389593.html
Copyright © 2020-2023  润新知