美文网首页
new operator, operator new, plac

new operator, operator new, plac

作者: hellowenqi | 来源:发表于2017-06-07 11:09 被阅读67次

本文参考地址 http://www.cnblogs.com/luxiaoxun/archive/2012/08/10/2631812.html

new operator

就是new 操作符:

  • 调用 operator new 分配足够的内存空间,调用对象的构造函数
  • 不能被重载
operator new

是函数:

  • 只分配内存,不调用构造函数
  • 可以被重载
  • 重载时,返回值类型必须声明为void *
  • 重载时,第一个参数必须是要求分配空间的字节大小,类型是 size_t
  • 重载时,允许携带其他参数。

例子:

#include <iostream>
#include <string>
using namespace std;

class X{
public:
  X(){
    cout<<"constructor"<<endl;
  }
  
  void* operator new(size_t size, string str){
    cout<< "operator new " << size <<  "  " <<  str << endl;
    return ::operator new(size);
  }   
  void operator delete(void* pointer){
     cout << "operator delete" <<endl;
     ::operator delete(pointer);
  }

  ~X(){
    cout<<"destructor"<<endl;
  }
};

int main(){
  X *x = new ("str") X;
  delete x;
  return 1;
}
placement new

placement new 是重载operator new 的一个标准、全局的版本,它不能够被自定义的版本代替(不像普通版本的operator new和operator delete能够被替换)。原型为:

void *operator new( size_t, void * p ) throw() { return p; }

placement new 的执行忽略了size_t参数,只返还第二个参数。其结果是允许用户把一个对象放到一个特定的地方,达到调用构造函数的效果。和其他普通的new不同的是,它在括号里多了另外一个参数。

palcement new 存在理由

  • 空间。不分配新的内存,而是构造一个新对象到预分配的内存上。
  • 时间。new 操作符分配内存,需要在堆上查询足够大的内存空间,而且会存在不能分配的异常(内存不足);placement new 是在已有的内存上构造对象,不查找内存,分配内存的时间复杂度为常数,且不存在内存分配异常的情况。适合时间要求高和长时间允许不被打断的程序。

placement 使用需要五步

  • 缓存提前分配,有三种方式:

  • 在堆上进行分配class Task :
    char * buff = new [sizeof(Task)];

  • 在栈上进行分配class Task:
    char buf[N*sizeof(Task)];

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

void* buf = reinterpret_cast<void*> (0xF00F);
  • 第二步:对象的分配
    刚才已分配的缓存区调用placement new来构造一个对象:
Task *ptask = new (buf) Task
  • 第三步:使用
    按照普通方式使用分配的对象:
ptask->memberfunction();
ptask->member;
  • 第四步:对象的析构
    一旦你使用完这个对象,你必须调用它的析构函数来毁灭它。
ptask->~Task(); //调用外在的析构函数

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

delete [] buf;

跳过任何步骤就可能导致运行时间的崩溃,内存泄露,以及其它的意想不到的情况。如果你确实需要使用placement new,请认真遵循以上的步骤。

#include <iostream>
using namespace std;

class X
{
public:
    X() { cout<<"constructor of X"<<endl; }
    ~X() { cout<<"destructor of X"<<endl;}

    void SetNum(int n)
    {
        num = n;
    }

    int GetNum()
    {
        return num;
    }

private:
    int num;
};

int main()
{
    char* buf = new char[sizeof(X)];
    X *px = new(buf) X;
    px->SetNum(10);
    cout<<px->GetNum()<<endl;
    px->~X();
    delete []buf;

    return 0;
}

相关文章

网友评论

      本文标题:new operator, operator new, plac

      本文链接:https://www.haomeiwen.com/subject/czeofxtx.html