C++中的 new
和 delete
操作符是用来管理动态内存分配的。在某些情况下,我们需要对 new
和 delete
进行重载,以满足我们特定的需求。但是重载这些操作符需要特别注意一些问题。
为什么需要重载?
一些使用场景:
- 改变内存分配行为,比如使用某种特殊的内存池来提高内存分配性能。
- 跟踪某些内存分配和释放,例如在调试模式下记录分配的位置和大小,释放正确性。
- 封装低级分配机制,在用户代码中只使用一个类似机制,让决策只发生在自定义类或内存池中。
重载new和delete
示例1
class MyClass
{
public:
void* operator new(size_t size)
{
cout << "Allocating " << size << " bytes" << endl;
void* ptr = malloc(size);
return ptr;
}
void operator delete(void* ptr)
{
cout << "Deleting the memory pointed to by ptr" << endl;
free(ptr);
}
};
int main()
{
MyClass *p = new MyClass();
delete p;
return 0;
}
上述示例中,我们重载了 new
和 delete
操作符。new
运算符接受一个参数,是要分配的字节数,我们在里面输出要分配的字节数,并使用标准库函数 malloc
进行内存分配。同时,我们还重载了 delete
对释放后的内存进行释放,并输出了一条日志信息。
示例2
class MyClass
{
public:
static size_t count;
void* operator new(size_t size)
{
++count;
void* ptr = malloc(size);
return ptr;
}
void operator delete(void* ptr)
{
--count;
free(ptr);
}
};
size_t MyClass::count = 0;
int main()
{
cout << "Allocating MyClass object..." << endl;
MyClass *p = new MyClass();
cout << "The number of allocated MyClass objects is:" << MyClass::count << endl;
delete p;
return 0;
}
在示例2中,我们重载了 new
和 delete
操作符。我们使用了一个静态变量 count
来记录创建的 MyClass
的对象数目。每次调用 new
运算符时,我们都会增加 count
的值,并在每次调用 delete
运算符时,都会减少 count
的值。这能够帮助我们跟踪当前分配和释放的对象数量。
注意事项
在进行 new
和 delete
操作符的重载时,需要注意以下几点:
- 通常应该同时重载
new
和delete
。 - 重载后的
new
和delete
需要和普通的new
和delete
有相同的签名。 - 重载操作符时,尽量保证其能够像普通的操作符一样使用,不要引入额外的闭包(特别是 lambda 表达式)。
- 重载的
new
和delete
操作符应该有类似try
块的功能,即在分配失败时返回nullptr
。 - 不要在重载的
new
操作符中使用非标准的分配方式,这可能导致代码无法在不同的编译器和平台上编译。
重载new[]和delete[]
在重载 new[]
和 delete[]
操作符时,应该注意与上面几点相同的事项。唯一不同之处在于, new[]
和 delete[]
需要使用数组的语法,因此需要额外的参数。
以下示例将演示 new[]
和 delete[]
操作符的重载:
class MyArray
{
public:
static size_t count;
void* operator new[](size_t size)
{
++count;
void* ptr = malloc(size);
return ptr;
}
void operator delete[](void* ptr)
{
--count;
free(ptr);
}
};
size_t MyArray::count = 0;
int main()
{
cout << "Allocating an array of MyArray objects..." << endl;
MyArray *arr = new MyArray[5];
cout << "The number of allocated MyArray objects is: " << MyArray::count << endl;
delete[] arr;
return 0;
}
在上面的示例中,我们重载了 new[]
和 delete[]
操作符。我们使用了一个静态变量 count
来记录创建的 MyArray
的对象数目。每次调用 new[]
运算符时,我们都会增加 count
的值,并在每次调用 delete[]
运算符时,都会减少 count
的值。这能够帮助我们跟踪当前分配和释放的对象数量。
总结:
重载 new
和 delete
对操作符时需要注意相同的事项。重载 new
和 delete
操作符可以让我们改变默认的内存分配方式,从而更好地控制程序的动态内存。但是,我们应该在重载操作符时严格遵循其规则,避免出现重载后的内存分配和释放的问题。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C++ new、delete(new[]、delete[])操作符重载需要注意的问题 - Python技术站