重载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); }

c/c++ 重载new,delete运算符 placement new的更多相关文章

  1. C++重载new和delete运算符

    内存管理运算符 new.new[].delete 和 delete[] 也可以进行重载,其重载形式既可以是类的成员函数,也可以是全局函数.一般情况下,内建的内存管理运算符就够用了,只有在需要自己管理内 ...

  2. C++学习32 重载new和delete运算符

    内存管理运算符 new.new[].delete 和 delete[] 也可以进行重载,其重载形式既可以是类的成员函数,也可以是全局函数.一般情况下,内建的内存管理运算符就够用了,只有在需要自己管理内 ...

  3. 重载new和delete运算符

    内存管理运算符 new.new[].delete 和 delete[] 也可以进行重载,其重载形式既可以是类的成员函数,也可以是全局函数.一般情况下,内建的内存管理运算符就够用了,只有在需要自己管理内 ...

  4. C++ new operator, delete operator, operator new, operator delete, new placement

    http://www.younfor.com/cpp-new-placement-new-operator-new.html http://www.cnblogs.com/luxiaoxun/arch ...

  5. C++重载流插入运算符和流提取运算符【转】

    C++的流插入运算符“<<”和流提取运算符“>>”是C++在类库中提供的,所有C++编译系统都在类库中提供输入流类istream和输出流类ostream.cin和cout分别是 ...

  6. C++运算符重载——输入/输出运算符

    为了与IO标准库一致,重载输入输出运算符函数的第一个行参应该是流的引用,第二个行参是对象的引用. 如果重载为类的成员函数,第一个行参应该是对象的引用,第二个行参是流的引用. 使用方式是 ClassOb ...

  7. operator 重载内置运算符

    operator 关键字来重载内置运算符,或提供类或结构声明中的用户定义转换.它可以定义不同类型之间采用何种转化方式和转化的结果. operator用于定义类型转化时可采用2种方式,隐式转换(impl ...

  8. C++中不可重载5个运算符

    C++中不可重载的5个运算符 C++中的大部分运算符都是可以重载的,只有以下5个运算符不可以重载,他们是: 1  .(点运算符)通常用于去对象的成员,但是->(箭头运算符),是可以重载的   2 ...

  9. 用new和delete运算符进行动态分配和撤销存储空间

    測试描写叙述:暂时开辟一个存储空间以存放一个结构体数据 #include <iostream> #include <string> using namespace std; s ...

随机推荐

  1. CSS实例详解:Flex布局

    本文由云+社区发表 本文将通过三个简单的实例,实际应用上篇文章的基础理论知识,展示下Flex布局是如何解决CSS布局问题. 一.垂直居中 这里同时用非flex布局和flex布局两种方式来实现,可以对比 ...

  2. Ubuntu 安装网卡驱动

    搭建Linux平台的无线热点,需要无线网卡和驱动都要支持 AP. 试了下Ubuntu平台默认驱动并不支持AP模式,所以需要更换驱动,具体操作步骤如下: 1.找到自己网卡芯片的型号,由于我的环境是搭建在 ...

  3. Perl文件句柄相关常量变量

    文件句柄相关变量 对应的官方手册:http://perldoc.perl.org/perlvar.html#Variables-related-to-filehandles 默认情况下: $/:输入行 ...

  4. vue-element-admin项目install出现的问题

    1.需要安装nodejs和git 2. 配置淘宝镜像源(经常是因为墙的原因下载缓慢或者出错) npm config set registry https://registry.npm.taobao.o ...

  5. 18.QT-QPlainEdit 信号与槽

    QPlainEdit编辑功能 Public Slots void appendHtml ( const QString & html ) void appendPlainText ( cons ...

  6. (一):C++分布式实时应用框架----整体介绍

    C++分布式实时应用框架 (Cpp Distributed Real-time Application Framework) 版权声明:本文版权及所用技术归属smartguys团队所有,对于抄袭,非经 ...

  7. JavaScript定时器实现的原理分析

    原文链接:http://www.cnblogs.com/st-leslie/p/6082450.html 一.储备知识 在我们在项目中一般会遇见过这样的两种定时器,第一种是setTimeOut,第二种 ...

  8. idea输入法不跟随解决办法

    最近使用idea开发项目,遇到输入法不跟随的问题,自己动手解决了下 idea输入法不跟随解决办法: 1):系统:windows10 版本:idea2017.2 解决办法:使用QQ输入法 2):系统:w ...

  9. Laravel 系列入门教程(三)【最适合中国人的 Laravel 教程】

    在本篇文章中,我们将尝试构建一个带后台的简单博客系统.我们将会使用到 路由.MVC.Eloquent ORM 和 blade 视图系统. 简单博客系统规划 我们在教程一中已经新建了一个继承自 Eloq ...

  10. struts2框架-----Action

    控制器Action Action对象是struts2框架的核心,每个URL映射到特定的Action,其提供处理来自用户的请求所需要的处理逻辑.Action有两个重要的功能,即将数据从请求传递到视图和协 ...