C++应用程序中申请内存基于分配器的实现(std::allocator),而分配器基于C++primitives(new,new[]…),c++primitives基于C语言中的malloc/free…当然越底层的函数效率越高。
那我们会想,直接用最底层的实现多好,效率还高.但如果你直接调用底层的函数去实现功能,虽然你的效率提高了,但你的程序的可移植性就会相应的降低.不可否认底层语言的实现,体现出一定的个人能力.但过多的篇幅去实现底层语言,会影响开发效率。
C++三种申请内存的方式:
a: new operator ,delete operator:申请内存 + 构造函数
b: new[],delete[]:用于数组类的操作
c: placement new :定点new
对应的代码:
int main()
{
void* p1 = malloc(512); //512bytes
free(p1);
complex<int>* p2 = new complex<int>; //one object
delete p2;
void* p3 = ::operator new(512);// 512bytes
::operator delete(p3);
//一下函数都是non-static,一定要通过object调用,分配7个int的内存
void* p4 = allocator<int>().allocate(7);//allocator<int>()创建临时对象
allocator<int>().deallocate((int*)p4,7);
return 0;
}
我们都知道 new = operator new + 构造函数,delete = 析构函数 + operator delete .如果以代码的形式表现出来应该是这样
比如我们创建一个复数类,
Complex* pc = new Complex(1,2);
try
{
void* mem = operator new(sizeof(Complex)); //allocate
pc = static_cast<Complex*>(mem); //cast
pc->Complex::Complex(1,2); //只有编译器可以直接调用构造函数
}
catch (std::bad_alloc)
{
//申请内存失败...
}
delete pc;
编译器翻译为:
pc-> ~Complex();//先调用析构函数
operator delete(pc); //operator的实现基于free()
placement new
placement new允许我们将object创建与 已经申请好的内存中,但是没有所谓的 placenment delete,因为根本没有分配内存,所以没有placement delete
char* buf = new char[sizeof(A) * 3];//申请了3个A的内存
A* pc = new(buf)A();//运用申请好的buf的内存,在buf上赋值
上面的new(buf)A();就是placement new.
编译器翻译:
A * pc;
try {
void* men = operator new(sizeof(A), buf); //借用内存
pc = static_cast<A*>(mem);//安全转换
pc->A::A();//构造函数
}
catch (std::bad_alloc){
//若失败 不执行构造函数
}