new 操作符是在堆中开辟一段内存空间,需要delete 来释放。
new 操作符其实有三种调用形式
void* operator new (std::size_t size) throw (std::bad_alloc);
void* operator new (std::size_t size, const std::nothrow_t& nothrow_constant) throw();
void* operator new (std::size_t size, void* ptr) throw();
第一个版本就是我们常用的
我们分配一个类型的大小的内存空间并且返回指向这段地址的指针
如果分配内存失败会抛出一个异常类bad_alloc exception, 并且返回NULL 指针
第二个版本我们指定了nothrow 这个参数,如果失败,不抛出任何东西。
在前两个版本中 new 这个操作会执行三个步骤
1 分配内存, 失败会根据版本不同,抛出内存会不抛
2 如果分配成功,且该类型是自定义类型 如一个类 就会调用其构造函数。内置类型没有这步
3 返回指向对应内存空间的指针
第三个版本比较特殊,我们不会分配定义类型的内存,会在已分配的内存上调用其构造函数,是其成为一个
对象
// operator new example
#include <iostream>
#include <new>
using namespace std;
struct myclass {myclass() {cout <<"myclass constructed\n";}};
int main () {
int * p1 = new int;
// 和下面一样 因为内置类型没有构造函数 无需初始化
// int * p1 = (int*) operator new (sizeof(int));
int * p2 = new (nothrow) int;
// 下面一样
// int * p2 = (int*) operator new (sizeof(int),nothrow);
myclass * p3 = (myclass*) operator new (sizeof(myclass));
// 知识分配了内存空间
// myclass * p3 = new myclass;
// (constructor not called by function call, even for non-POD types)
new (p3) myclass; // 调用构造函数
// 和下面的一样
// operator new (sizeof(myclass),p3)
return 0;
}
是分配一段内存连续的内存空间,
operator new[]
void* operator new[] (std::size_t size) throw (std::bad_alloc);
void* operator new[] (std::size_t size, const std::nothrow_t& nothrow_constant) throw();
void* operator new[] (std::size_t size, void* ptr) throw();
其用法和operator new 一样
// operator new[] example
#include <iostream>
#include <memory>
#include <new>
using namespace std;
struct myclass {myclass() {cout <<"myclass constructed\n";}};
int main () {
// 第一个版本
int * p1 = new int[5];
// 第二个版本
int * p2 = new (nothrow) int[4];
// 第三个版本
pair <myclass*,ptrdiff_t> p3 = get_temporary_buffer<myclass>(3);
new (p3.first) myclass[3]; // calls constructors
return_temporary_buffer(p3.first);
return 0;
}
第三个版本主要是内存池技术用得比较多, 省去在程序分配内存