面试题:"new"运算符和"new"函数有什么区别?
我回答没有区别,他们运行相同的代码,但面试官一直在挑刺我,好像那是错误的答案。
这是错误的答案吗?还是面试官在耍我?
如果答案是错误的,那么正确答案是什么?
我继续说,如果您需要自定义分配,可以重载"new"运算符,但后来他想知道如何重载它。当然我没有那个答案,从来没有需要,但我告诉他我可以在 10 分钟内查到(这在面试中永远不是正确的答案)。
所以无论如何,在对"new"运算符与"new"函数进行了一些研究之后,并没有看到任何真正令人满意的答案,我想我会问这个具体问题。
new
运算符和operator new
不是一回事。
new
运算符调用 operator new
函数来分配内存,然后根据分配的类型和使用的语法,初始化或调用分配的构造函数内存。也就是说,operator new
只是new
操作符的一部分。
operator new
是由new
运算符调用分配内存的函数。 operator new
有一个默认实现,可以替换,这与重载不同。 operator new
也可以为 a particular type 实现仅处理该类型对象的分配,或者可以重载 operator new
,并且可以使用 new
运算符的 placement 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;
要提供 operator new
的重载以与 new
运算符的放置形式一起使用,您可以添加额外的参数(operator new< 的 nothrow 版本
和 operator delete
执行此操作)。
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); // allocate an int using the operator new that takes a my_type object
delete
运算符没有“放置删除”形式。提供 operator delete
的重载是因为如果在内存的初始化/构造期间发生错误(例如, operator new 之后由 new
运算符调用的构造函数
已调用)如果在重新抛出异常之前存在,则调用相应的 operator delete
。否则 operator delete
不会被调用并且 the memory leaks抛出异常时。