加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c/c++ 重载new,delete运算符 placement new实例讲解

发布时间:2020-12-15 04:55:39 所属栏目:百科 来源:网络整理
导读:重载new,delete运算符 new,delete在c++中也被归为运算符,所以可以重载它们。 new的行为: 先开辟内存空间 再调用类的构造函数 开辟内存空间的部分,可以被重载。 delete的行为: 先调用类的析构函数 再释放内存空间 释放内存空间的部分,可以被重载。 为

重载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

#include

using namespace std;

class String{

public:

String(const char* str = ""){

cout << "Create" << endl;

if(NULL == str){

data = new char[1];

data[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,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);

}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读