【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时中括号放前面。