c/c++ 重载new,delete运算符 placement new

本文深入探讨了C++中new和delete运算符的重载方法,包括开辟和释放内存空间的过程,以及如何通过重载实现内存池,减少内存碎片,提高程序效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

重载new,delete运算符

new,delete在c++中也被归为运算符,所以可以重载它们。

new的行为:

  • 先开辟内存空间

  • 再调用类的构造函数

开辟内存空间的部分,可以被重载。

delete的行为:

  • 先调用类的析构函数

  • 再释放内存空间

释放内存空间的部分,可以被重载。

为什么要要重载它们?

有时需要实现内存池的时候需要重载它们。频繁的new和delete对象,会造成内存碎片,内存不足等问题,影响程序的正常执行,所以一次开辟一个适当大的空间,每次需要对象的时候,不再需要去开辟内存空间,只需要调用构造函数(使用placement new)即可。

new,delete的重载函数,可以是全局函数,也可以是类内部的公有重载函数;当既有全局的重载函数,也有类内部的公有重载函数时,实际调用的是类内部的公有重载函数。

new,delete可以有多种重载方式,但是,new函数的第一个参数一定要是size_t类型

重载方式1,new单个对象

void* operator new(size_t sz)

{

void* o = malloc(sz); return o;

}

void operator delete(void *o)

{

free(o);

}

重载方式2,new对象的数组

void* operator new[](size_t sz)

{

void* o = malloc(sz); return o;

}

void operator delete[](void *o)

{

free(o);

}

重载方式3,不开辟空间,只是调用给定对象(用地址识别)的构造方法,也叫placement new

//第一个参数size_t即使不使用,也必须有

void* operator new(size_t sz, String* s, int pos)

{

return s + pos;

}

小例子:

 

#include <iostream> #include <string.h> using namespace std; class String{ public: String(const char* str = ""){ cout << "Create" << endl; if(NULL == str){ data = new char[1]; data[0] = '\0'; } else{ data = new char[strlen(str) + 1]; strcpy(data, str); } } ~String(){ cout << "Free" << endl; delete []data; data = NULL; } private: char* data = NULL; }; //重载方式1 void* operator new(size_t sz){ cout << "in operator new" << endl; void* o = malloc(sz); return o; } void operator delete(void *o){ cout << "in operator delete" << endl; free(o); } //重载方式2 void* operator new[](size_t sz){ cout << "in operator new[]" << endl; void* o = malloc(sz); return o; } void operator delete[](void *o){ cout << "in operator delete[]" << endl; free(o); } //重载方式3 //第一个参数size_t即使不适用,也必须有 void* operator new(size_t sz, String* s, int pos){ return s + pos; } int main(){ String *s = new String("abc"); delete s; String *sr = new String[3]; delete []sr; //开辟内存池,但是还没有调用过池里对象的构造方法 String *ar = (String*)operator new(sizeof(String) * 2); //调用池里第一个对象的构造方法,不再开辟空间 new(ar, 0)String("first0"); //调用池里第二个对象的构造方法 ,不再开辟空间 new(ar, 1)String("first1"); //调用池里第一个对象的析构方法,注意不会释放到内存 (&ar[0])->~String(); //调用池里第二个对象的析构方法,注意不会释放到内存 (&ar[1])->~String(); //下面语句执行前,内存池里的对象可以反复利用 operator delete(ar); }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值