new和delete运算符也可以像C++中的其他运算符一样重载。 New和Delete运算符可以全局重载,也可以在特定类中重载。
- 如果这些运算符使用某个类的成员函数进行了重载,则意味着这些运算符仅对该特定类进行了重载。
- 如果重载是在类外部完成的(即它不是类的成员函数),则只要您使用这些运算符(在类内或类外),都将调用重载的“ new”和“ delete”。这是全局超载。
重载new运算符的语法:
void* operator new(size_t size);
重载的new运算符接收到size_t类型的大小,该大小指定要分配的内存字节数。重载的new的返回类型必须为void *。重载的函数返回一个指向分配的内存块开头的指针。
重载delete运算符的语法:
void operator delete(void*);
该函数接收一个必须删除的类型为void *的参数。函数不应该返回任何东西。
注意:默认情况下,重载的new和delete运算符函数都是静态成员。因此,他们无权访问此指针。
重载特定类的new和delete运算符:
CPP
// CPP program to demonstrate
// Overloading new and delete operator
// for a specific class
#include
#include
using namespace std;
class student
{
string name;
int age;
public:
student()
{
cout<< "Constructor is called\n" ;
}
student(string name, int age)
{
this->name = name;
this->age = age;
}
void display()
{
cout<< "Name:" << name << endl;
cout<< "Age:" << age << endl;
}
void * operator new(size_t size)
{
cout<< "Overloading new operator with size: " << size << endl;
void * p = ::operator new(size);
//void * p = malloc(size); will also work fine
return p;
}
void operator delete(void * p)
{
cout<< "Overloading delete operator " << endl;
free(p);
}
};
int main()
{
student * p = new student("Yash", 24);
p->display();
delete p;
}
CPP
// CPP program to demonstrate
// Global overloading of
// new and delete operator
#include
#include
using namespace std;
void * operator new(size_t size)
{
cout << "New operator overloading " << endl;
void * p = malloc(size);
return p;
}
void operator delete(void * p)
{
cout << "Delete operator overloading " << endl;
free(p);
}
int main()
{
int n = 5, i;
int * p = new int[3];
for (i = 0; i
C
void *operator new(size_t size, char c)
{
void *ptr;
ptr = malloc(size);
if (ptr!=NULL)
*ptr = c;
return ptr;
}
main()
{
char *ch = new('#') char;
}
Overloading new operator with size: 16
Constructor is called
Name:Yash
Age:24
Overloading delete operator
注意:在上面的新重载函数,我们已经通过new运算符分配了动态内存,但是它应该是global new运算符,否则它将递归进行
无效* p =新学生(); //这会递归,因为new会一次又一次地被重载
无效* p = :: new student(); // 这是对的
new和delete运算符的全局重载
CPP
// CPP program to demonstrate
// Global overloading of
// new and delete operator
#include
#include
using namespace std;
void * operator new(size_t size)
{
cout << "New operator overloading " << endl;
void * p = malloc(size);
return p;
}
void operator delete(void * p)
{
cout << "Delete operator overloading " << endl;
free(p);
}
int main()
{
int n = 5, i;
int * p = new int[3];
for (i = 0; i
输出 :
New operator overloading
Array: 0 1 2 3 4
Delete operator overloading
注意:在上面的代码中,在新的重载函数,我们无法使用:: new int [5]分配内存,因为它将以递归方式进行。我们只需要使用malloc分配内存。
为什么要重载new和Delete?
1.重载的new运算符函数可以接受参数;因此,一个类可以具有多个重载的新运算符功能。这为程序员提供了更大的灵活性,可以为对象自定义内存分配。例如:
C
void *operator new(size_t size, char c)
{
void *ptr;
ptr = malloc(size);
if (ptr!=NULL)
*ptr = c;
return ptr;
}
main()
{
char *ch = new('#') char;
}
2.注意:代码不仅将为单个字符分配内存,还将使用#字符初始化分配的内存。
3.重载的new或delete运算符还为类的对象提供了垃圾回收。
4.异常处理例程可以在重载的新运算符函数添加。
5.有时,您希望运算符new并删除它们,以执行一些编译器提供的版本不提供的自定义操作。例如,您可能会编写一个自定义运算符delete,以用0覆盖释放的内存,以提高应用程序数据的安全性。
6.我们可以在新函数使用realloc()函数动态地重新分配内存。
7.重载的新运算符还使程序员能够从程序中榨取一些额外的性能。例如,在一个类中,为了加快新节点的分配,维护了一个已删除节点的列表,以便在分配新节点时可以重用它们的内存。在这种情况下,重载的delete运算符会将节点添加到列表中删除的节点和重载的new运算符将从列表中分配内存,而不是从堆中分配内存以加快内存分配。当删除的节点列表为空时,可以使用堆中的内存。