当前位置:   article > 正文

重载new,delete运算符_delete操作符重载函数

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);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

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

void* operator new[](size_t sz){
  void* o = malloc(sz);
  return o;
}
void operator delete[](void *o){
  free(o);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

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

//第一个参数size_t即使不使用,也必须有                          
void* operator new(size_t sz, String* s, int pos){
  return s + pos;
}
  • 1
  • 2
  • 3
  • 4

小例子:

#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);

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Li_阴宅/article/detail/876194
推荐阅读
相关标签
  

闽ICP备14008679号