zoukankan      html  css  js  c++  java
  • 浅谈new operator、operator new和placement new 分类: C/C++ 2015-05-05 00:19 41人阅读 评论(0) 收藏

    浅谈new operator、operator new和placement new

    C++中使用new来产生一个存在于heap(堆)上对象时,实际上是调用了operator new函数和placement new函数。new即new operator,是C++保留的关键字,我们无法改变其含义,但我们可以改变new完成它功能时调用的两个函数,operator new()和placement new()。operator new()用于申请heap空间,功能类似于malloc(),placement new()用于在已经获得的堆空间上调用类构造函数。
    例如代码:

    string* sp=new string(“hello world”);

    等价于:

    string* sp=NULL;
    sp =operator new(strlen(“hello world”));//申请空间,行为类似于malloc
    new (sp) string(“hello world”);//调用string类的构造函数,初始化申请空间

    operator new()的函数原型:

    void* operator new(size_t sz);

    示例代码如下:

    void* operator new(size_t sz) throw(std::bad_alloc)
    {
      cerr << "allocating " << sz << " bytesn "<<endl;
      void* mem = malloc(sz);
      if (mem)
        return mem;
      else
        throw std::bad_alloc();
    }

    注意:
    1. 函数后添加throw表示可能会抛出throw后括号内的异常。
    2. operator new()分为全局和类成员。当为类成员函数时,使用new产生类对象时调用的则是其成员函数operator new()。


    placement new()的函数原型是:

    void* operator new(std::size_t, void* __p);

    示例代码如下:

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

    注意:
    1. placement new()的函数原型不是void* placement new(std::size_t, void* __p);
    2. placement new只是operator new()的一个重载,多了一个已经申请好的空间,由void* __p指定。
    3. 用法是new (addr) constructor():对addr指定的内存空间调用构造函数进行初始化。为何称为placement new,从其用法可以看出只是用于调用构造函数。
    总结:
    1. 若想在堆上建立一个对象,应该用new操作符。它既分配内存又调用其构造函数进行初始化。
    2. 若仅仅想分配内存,应该调用operator new(),他不会调用构造函数。若想定制自己在堆对象被建立时的内存分配过程,应该重写自己的operator new()。
    3. 若想在一块已经获得的内存空间上建立一个对象,应该用placement new。虽然在实际开发过程中,很少需要重写operator new(),使用内置的operator new()即可完成大部分程序所需的功能。但知道这些,有助于一个C++程序猿对C++内存的管理有个清楚的认识。


    了解delete和operator delete():
    为了避免内存泄漏,每个动态内存分配必须与一个等同相反的 deallocation 对应。数operator delete与delete操作符的关系与operator new与new操作符是一样的。delete用于使用使用new申请的空间,operator delete用于释放operator new申请的空间(类似于malloc与free),那谁来清理placement new初始化的内存内容呢?唯一办法就是调用对象的析构函数。
    示例代码:

    string* sp=new string(“hello world”);
    delete sp;

    第一行代码在上文已经剖析,那么当调用delete sp时,发生了什么?
    delete sp等价于:

    ps->~string(); //用于清理内存内容,对应placement new
    operator delete(ps);//释放内存空间,对应于operator new()

    其中operator delete()的函数原型为:

    void operator delete(void *memoryToBeDeallocated);

    参考文献:
    [1]Scott Meyers.More Effective C++(第三版)[M].北京:电子工业出版社,2011.1.
    [2]zjdtc的博客-新浪博客.operator new在C++中的各种写法. http://blog.sina.com.cn/s/blog_3c6889fe0100tqe8.html

    版权声明:本文为博主原创文章,未经博主允许不得转载。

    ---转载或者使用代码,请注明原作者 This is bill
  • 相关阅读:
    [swustoj 1021] Submissions of online judge
    [swustoj 404] 最小代价树
    [swustoj 917] K-lucky-number
    [swustoj 183] 种树
    [LA 3887] Slim Span
    [ahu 1248] NBA Finals
    用js获取当前月份的天数
    WampServer
    jquery checkbox选中、改变状态、change和click事件
    为什么排版引擎解析 CSS 选择器时一定要从右往左解析?
  • 原文地址:https://www.cnblogs.com/ScytheWH/p/4622978.html
Copyright © 2011-2022 走看看