【M8】了解各种不同意义的new和delete

时间:2023-03-08 20:21:17
【M8】了解各种不同意义的new和delete

1、首先考虑new operator,new operator 可以认为做了三件事情:a、调用operator new分配一块内存;b、在这块内存上调用构造方法构造对象;返回指针。

2、operator new的声明如下:

  void* operator new(size_t size)

  和C中的malloc一样,operator new只负责分配内存。

3、考虑,string* ps = new string("hello"); 相当于做了下列事情:

  a、void* memory = operator new (sizeof(string));

  b、在*memory上面,调用string::string("hello"),构造对象;

  c、返回指针,string* ps = static_cast<string*>(memory).

4、上面通过operator new 试图分配一块内存。这存在两个问题:a、底层接口通过一定算法分配一块可用的内存,有可能是耗时的;b、也许无法分配一块可用的内存。因此,就有了下面的需求:我提前分配一块内存,然后在这块内存上调用构造方法,构造对象,该怎么办呢?如下:

  Widget* ConstructWidgetOnBuffer(void* buffer, int widgetSize)

  {

    return new (buffer) Widget(widgetSize);

  }

  这里的new operator不同于正常的new operator,中间有个(buffer)。这里的new operator调用placement new,placement new 声明如下:

  void* operator new(size_t, void* location)

  {

    return location;

  }

5、考虑,delete operator,可认为做了两件事:a、指向对象调用析构方法;b、执行operator delete释放内存。如下:

  string* ps; delete ps; 相当于:

  ps->~string();

  operator delete(ps);

6、如果只是处理原始,未设初值的内存,不应该使用new operator和delete operator,而应该使用operator new和operator delete,如下:

  void* buffer = operator new(20);

  operator delete(buffer)

  这类似于C中的方法malloc和free。

7、特别注意:new与delete的使用要匹配。分别是:

  a、operator new 对应operator delete,前面不构造,后面不析构;

  b、new operator对应delete operator;

  c、对于placement new 不能使用delete operator,因为前者并不分配内存,只是使用已有的内存构造对象,而delete operator会释放内存,而这块内存别人可能还在使用。因此,应该只是调用析构方法;

  d、是否带有[],new operator 和delete operator要匹配。如:string* ps = new string[10];  delete [] ps; delete时中括号放前面。