loki库中DefaultAlloc中介绍了c++目前支持的new 和 delete相关的操作
我们知道new操作实际包含两个步骤:operator new:分配内存,构造函数调用。
而operator new我们是可以重载的
相对的delete操作也包含两个步骤,析构函数调用,析构内存.
另外简单了解下分配内存过程:vs实现中会调用C的mallo,再调用操作系统的HeapAlloc,操作系统分配内存有HeapAlloc和virtualAlloc,分配大内存可以考虑virtualAlloc。一般情况下建议使用new和delete即可,编译器内部会适当的调用合适的api接口
编译器类型,版本获取,以vs为例
#elif (_MSC_VER >= 1400)
return "Microsoft 8.0 or higher";
#elif (_MSC_VER >= 1300)
return "Microsoft 7";
#elif (_MSC_VER >= 1200)
return "Microsoft 6";
#elif (_MSC_VER)
return "Microsoft, but a version lower than 6";
new的重载形式
1、void * operator new ( std::size_t size ) throw(std bad_alloc)
我们调用的最常见形式,举例
CTestPtr* pA1 = new CTestPtr;
2、void * operator new ( std::size_t size, const std::nothrow_t & nt ) throw ()
不抛出异常的形式,nothrow_t是一个结构体,而std::nothrow是一个对象,通过类型识别函数重载调用的这个函数
struct nothrow_t
{ // placement new tag type to suppress exceptions
};
extern const nothrow_t nothrow; // constant for placement new tag
举例
CTestPtr* pA2 = new(std::nothrow)CTestPtr;
3、void * operator new ( std::size_t size, void * place )
在place内存位置调用构造函数,使用举例。new的调用都是new(第二个参数),第一个参数固定为size_t
void* pA = ::operator new(sizeof(CTestPtr));
CTestPtr* pa = new(pA)CTestPtr;
delete的重载形式
1、void operator delete ( void * place, std::size_t size ) throw ()
2、void operator delete ( void * place, const std::nothrow_t & nt ) throw()
3、void operator delete ( void * place1, void * place2 )
调用delete操作符是不会调用析构函数的
CTestPtr* pA1 = new CTestPtr;
::operator delete(pA1); // 调用的是delete接口,释放内存,不会调用析构函数
// delete pA1;// 会先调用析构函数,再调用delete释放内存
// delete(PA1)和delete pA1效果一样,这个没怎么想明白