C++:operator new/delete函数
每个类默认都会有一个全局范围的 operator new
和 operator delete
接口,它们是由标准库提供的,可以用于动态内存分配和释放。如果一个类没有显式定义自己的 operator new
或 operator delete
,默认的全局版本会被使用。
默认 operator new
的特点
-
定义:
- 默认的
operator new
在<new>
头文件中定义。 - 它分配一块指定大小的内存(以字节为单位),并返回其地址。
- 默认的
-
实现(概念上):
void* operator new(std::size_t size) { if (void* p = std::malloc(size)) // 使用 malloc 分配内存 return p; throw std::bad_alloc(); // 如果分配失败,抛出异常 }
-
全局版本:
默认情况下,所有类都使用全局范围的operator new
和operator delete
:void* operator new(std::size_t size); void operator delete(void* ptr) noexcept;
-
例子:
class MyClass { public: int x; }; MyClass* obj = new MyClass(); // 使用全局的 operator new 分配内存 delete obj; // 使用全局的 operator delete 释放内存
自定义 operator new
可以为某个类自定义 operator new
和 operator delete
,从而覆盖默认行为。例如:
-
自定义类专属的
operator new
:class MyClass { public: void* operator new(std::size_t size) { std::cout << "MyClass::operator new called\n"; return std::malloc(size); // 自定义内存分配逻辑 } void operator delete(void* ptr) noexcept { std::cout << "MyClass::operator delete called\n"; std::free(ptr); // 自定义内存释放逻辑 } }; MyClass* obj = new MyClass(); // 调用 MyClass 自定义的 operator new delete obj; // 调用 MyClass 自定义的 operator delete
-
自定义操作对其他类的影响:
- 自定义的
operator new
和operator delete
只适用于该类及其派生类,不会影响其他类或全局的内存分配行为。 - 如果调用的是全局范围的
new
和delete
,将使用默认版本。
- 自定义的
全局 operator new
除了类的自定义版本,可以重载全局范围的 operator new
和 operator delete
:
-
重载全局版本:
void* operator new(std::size_t size) { std::cout << "Global operator new called\n"; return std::malloc(size); } void operator delete(void* ptr) noexcept { std::cout << "Global operator delete called\n"; std::free(ptr); }
-
影响范围:
- 所有未自定义
operator new
的类都会使用全局版本。
- 所有未自定义
注意事项
-
静态对象和栈对象:
- 对于静态或栈分配的对象,
operator new
和operator delete
不会被调用。 - 它们只针对动态分配的内存。
MyClass obj; // 不会调用 operator new 或 operator delete
- 对于静态或栈分配的对象,
-
继承与多态:
- 如果基类和派生类分别定义了
operator new
,则会根据具体类调用对应的版本。
- 如果基类和派生类分别定义了
-
内存对齐:
- 默认版本的
operator new
保证分配的内存满足类型的对齐要求。 - 如果需要特殊对齐,可以重载带对齐参数的
operator new
。
- 默认版本的
总结
- 默认的
operator new
和operator delete
是全局提供的,所有类默认都会使用它们。 - 可以自定义某个类的
operator new
和operator delete
,以满足特定的内存分配需求。 - 对于动态内存管理,C++ 提供了很高的灵活性和可控性,但同时需要谨慎处理以避免内存泄漏和错误。