new
运算符和
operator new
并不是同一件事。
new
运算符调用
operator new
函数来分配内存,然后根据所分配的类型和使用的语法,初始化或在分配的内存上调用构造函数。换句话说,
operator new
只是
new
运算符操作的一部分。
operator new
是由
new
运算符调用以分配内存的函数。有一个默认实现的
operator new
可以被替换,这与重载不同。也可以为
特定类型实现
operator new
以仅处理该类型对象的分配,或者可以重载
operator new
并使用
new
运算符的放置形式选择重载。
可以通过定义以下签名的函数来替换
operator new
的默认实现:
void *operator new(std::size_t size);
void *operator new(std::size_t size, const std::nothrow_t&);
void *operator new[](std::size_t size);
void *operator new[](std::size_t size, const std::nothrow_t&);
当你提供operator new
的替换或重载函数时,应该同时提供相应的operator delete
函数:
void operator delete(void* ptr) noexcept;
void operator delete(void* ptr, const std::nothrow_t&) noexcept;
void operator delete[](void* ptr) noexcept;
void operator delete[](void* ptr, const std::nothrow_t&) noexcept;
要为new
运算符的放置形式提供operator new
的重载,您可以添加附加参数(operator new
和operator delete
的nothrow版本会这样做)。
struct my_type {};
void *operator new(std::size_t size, const my_type&);
void operator delete(void *ptr, const my_type&);
new (my_type()) int(10);
不存在“placement delete”形式的delete
运算符。提供了operator delete
的重载,因为如果在内存的初始化/构造期间发生错误(例如,在operator new
调用后由new
运算符调用的构造函数中),则在重新抛出异常之前,会调用相应的operator delete
(如果存在)。否则,在抛出异常时operator delete
不会被调用,从而导致内存泄漏。