一、operator new /operator delete里面有this指针吗
在C++中,operator new
和 operator delete
是用来管理内存分配和释放的全局函数或者类成员函数。它们与通常的成员函数不同,不会隐式地接收一个 this
指针。这是因为 new
和 delete
不是对象的方法,而是语言的关键字,用于动态内存管理。
当在类的上下文中重载这些运算符时,它们通常被声明为静态成员函数,因为它们不需要访问类的实例数据。下面是一个例子:
class MyClass {
public:
static void* operator new(size_t size) {
// 自定义内存分配逻辑
void* memory = malloc(size);
return memory;
}
static void operator delete(void* ptr) noexcept {
// 自定义内存释放逻辑
free(ptr);
}
};
在这个例子中,operator new
和 operator delete
都是静态成员函数,它们没有 this
指针。当使用 new
和 delete
关键字时,编译器会调用这些重载的运算符,但是它们不依赖于任何特定的对象实例。
全局版本的 operator new
和 operator delete
也不存在 this
指针的概念,因为它们是全局函数,不隶属于任何类。
注意,operator new
返回的是一个指向分配的内存的原始指针,而 operator delete
接受一个指向要释放的内存的原始指针。它们不会自动调用构造函数或析构函数,这是 new
表达式和 delete
表达式的职责。
二、将operator new/delete函数放在类外且不加类名与作用域限定符,会产生什么现象,该如何解释?
将 operator new
和 operator delete
定义在类外,并且不加上类名和作用域限定符,实际上就是定义了全局的重载版本。这意味着你正在重载全局的 new
和 delete
运算符,而不是特定类的版本。
全局的 operator new
和 operator delete
将会影响到所有使用 new
和 delete
运算符的地方,除非有更具体的重载(比如特定类的成员重载)优先匹配。全局重载可以用来实现一些通用的内存管理策略,例如统一的日志记录、内存池、内存跟踪等。
这里是如何定义一个全局的 operator new
和 operator delete
:
void* operator new(size_t size) {
void* memory = malloc(size);
if (memory == nullptr) {
// 处理内存分配失败的情况
throw std::bad_alloc();
}
return memory;
}
void operator delete(void* ptr) noexcept {
free(ptr);
}
这样的重载会捕获所有未指定特定类重载的 new
和 delete
调用。然而,这可能不是最佳实践,因为它可能干扰到其他部分的代码,尤其是当你的代码与其他库混合使用时,这些库可能期望默认的行为或者是它们自己定义的重载行为。
通常,更推荐的做法是在每个类中局部重载 operator new
和 operator delete
,这样可以控制每个类的内存分配和释放行为,同时避免对全局行为造成影响。如果需要全局的内存管理策略,可以考虑使用自由函数或者模板函数,并在需要的地方显式调用,而不是通过重载运算符。