📜  重载C++中的New和Delete运算符

📅  最后修改于: 2021-05-30 17:09:01             🧑  作者: Mango

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运算符将从列表中分配内存,而不是从堆中分配内存以加快内存分配。当删除的节点列表为空时,可以使用堆中的内存。

要从最佳影片策划和实践问题去学习,检查了C++基础课程为基础,以先进的C++和C++ STL课程基础加上STL。要完成从学习语言到DS Algo等的更多准备工作,请参阅“完整面试准备课程”