文章目录

  • 1 new和delete操作符重载
    • 1.1 new和delete操作符重载简介
    • 1.2 静态存储区中创建动态对象
    • 1.3 在指定的地址上创建C++对象
  • 2 new[]和delete[]操作符重载

1 new和delete操作符重载

1.1 new和delete操作符重载简介

new/delete的本质是C++预定义的操作符,C++对这两个操作符做了严格的行为定义:

  • new:

    1. 获取足够大的内存空间(默认为堆空间)。
    2. 在获取的空间中调用构造函数创建对象。
  • delete:
    1. 调用析构函数销毁对象。
    2. 归还对象所占用的空间(默认为堆空间)。

在C++中能够重载new/delete操作符:

  • 全局重载(不推荐)
  • 局部重载(针对具体类进行重载)

重载new/delete的意义在于改变动态对象创建时的内存分配方式。

new和delete的重载方式:

需要注意的点:

  • new操作符重载函数返回后编译器会自动调用构造函数。
  • delete操作符重载函数调用前编译器会自动调用析构函数。

1.2 静态存储区中创建动态对象

#include <iostream>
#include <string>using namespace std;class Test
{static const unsigned int COUNT = 4;static char c_buffer[];static char c_map[];int m_value;
public:void* operator new (unsigned int size){void* ret = NULL;for(int i=0; i<COUNT; i++){if( !c_map[i] ){c_map[i] = 1;ret = c_buffer + i * sizeof(Test);cout << "succeed to allocate memory: " << ret << endl;break;}}return ret;}void operator delete (void* p){if( p != NULL ){char* mem = reinterpret_cast<char*>(p);int index = (mem - c_buffer) / sizeof(Test);int flag = (mem - c_buffer) % sizeof(Test);if( (flag == 0) && (0 <= index) && (index < COUNT) ){c_map[index] = 0;cout << "succeed to free memory: " << p << endl;}}}
};char Test::c_buffer[sizeof(Test) * Test::COUNT] = {0};
char Test::c_map[Test::COUNT] = {0};int main(int argc, char *argv[])
{cout << "===== Test Single Object =====" << endl;Test* pt = new Test;delete pt;cout << "===== Test Object Array =====" << endl;Test* pa[5] = {0};for(int i=0; i<5; i++){pa[i] = new Test;cout << "pa[" << i << "] = " << pa[i] << endl;}for(int i=0; i<5; i++){cout << "delete " << pa[i] << endl;delete pa[i];}return 0;
}

1.3 在指定的地址上创建C++对象

解决方案:

  • 在类中重载new/delete操作符。
  • 在new的操作符重载函数中返回指定的地址。
  • 在delete操作符重载中标记对应的地址可用。

编程实验:自定义动态对象的存储空间

#include <iostream>
#include <string>
#include <cstdlib>using namespace std;class Test
{static unsigned int c_count;static char* c_buffer;static char* c_map;int m_value;
public:static bool SetMemorySource(char* memory, unsigned int size){bool ret = false;c_count = size / sizeof(Test);ret = (c_count && (c_map = reinterpret_cast<char*>(calloc(c_count, sizeof(char)))));if( ret ){c_buffer = memory;}else{free(c_map);c_map = NULL;c_buffer = NULL;c_count = 0;}return ret;}void* operator new (unsigned int size){void* ret = NULL;if( c_count > 0 ){for(int i=0; i<c_count; i++){if( !c_map[i] ){c_map[i] = 1;ret = c_buffer + i * sizeof(Test);cout << "succeed to allocate memory: " << ret << endl;break;}}}else{ret = malloc(size);}return ret;}void operator delete (void* p){if( p != NULL ){if( c_count > 0 ){char* mem = reinterpret_cast<char*>(p);int index = (mem - c_buffer) / sizeof(Test);int flag = (mem - c_buffer) % sizeof(Test);if( (flag == 0) && (0 <= index) && (index < c_count) ){c_map[index] = 0;cout << "succeed to free memory: " << p << endl;}}else{free(p);}}}
};unsigned int Test::c_count = 0;
char* Test::c_buffer = NULL;
char* Test::c_map = NULL;int main(int argc, char *argv[])
{char buffer[12] = {0};Test::SetMemorySource(buffer, sizeof(buffer));cout << "===== Test Single Object =====" << endl;Test* pt = new Test;delete pt;cout << "===== Test Object Array =====" << endl;Test* pa[5] = {0};for(int i=0; i<5; i++){pa[i] = new Test;cout << "pa[" << i << "] = " << pa[i] << endl;}for(int i=0; i<5; i++){cout << "delete " << pa[i] << endl;delete pa[i];}return 0;
}

2 new[]和delete[]操作符重载

new[]/delete[]和new/delete完全不同:

  • 动态对象数组创建通过new[]完成。
  • 动态对象数组的销毁通过delete[]完成。
  • new[]/delete[]能够被重载,进而改变内存管理方式。

new[]/delete[]的重载方式:

注意事项:

  • new[]实际需要返回的内存空间可能比期望的要多。
  • 对象数组占用的内存中需要保存数组信息。
  • 数组信息用于确定构造函数和析构函数的调用次数。

编程实验:动态数组的内存管理

#include <iostream>
#include <string>
#include <cstdlib>using namespace std;class Test
{int m_value;
public:Test(){m_value = 0;}~Test(){}void* operator new (unsigned int size){cout << "operator new: " << size << endl;return malloc(size);}void operator delete (void* p){cout << "operator delete: " << p << endl;free(p);}void* operator new[] (unsigned int size){cout << "operator new[]: " << size << endl;return malloc(size);}void operator delete[] (void* p){cout << "operator delete[]: " << p << endl;free(p);}
};int main(int argc, char *argv[])
{Test* pt = NULL;pt = new Test;delete pt;pt = new Test[5];delete[] pt;return 0;
}

参考资料:

  1. C++深度解析教程

C++中的new和delete操作符重载相关推荐

  1. C++ 面向对象(二)—— 操作符重载

    C++ 实现了在类(class)之间使用语言标准操作符,而不只是在基本数据类型之间使用.例如: int a, b, c; a = b + c; 是有效操作,因为加号两边的变量都是基本数据类型.然而,我 ...

  2. C++基础11-类和对象之操作符重载2

    总结: 1.等号操作符重载和拷贝构造函数重载一般用在数据成员中需要单独在堆区开辟内存时(指针) 2.new,delete重载内部还是使用malloc和free 3.逗号表达式(,).或者(||),且( ...

  3. 操作符重载——C/C++学习笔记

    此篇文章来自于网上,作为自己学习中的笔记,若有侵权行为,请告之,24小时之内必删除!下面就转入正题吧! 一.什么是操作符重载? 一看到重载,很容易就让人联想到成员函数重载,函数重载可以使名称相同的函数 ...

  4. C++中的指针特征操作符重载

    文章目录 1 C++中的指针特征操作符重载 1.1 指针特征操作符重载 1.2 使用指针特征操作符重载实现智能指针 1 C++中的指针特征操作符重载 1.1 指针特征操作符重载 指针特征操作符重载: ...

  5. C++中的赋值操作符重载

    文章目录 1 C++中的赋值操作符重载 1.1 赋值操作符重载 1 C++中的赋值操作符重载 1.1 赋值操作符重载 关于赋值操作符: 编译器为每个类默认重载了赋值操作符. 默认的赋值操作符仅完成浅拷 ...

  6. c++重载运算符_C/C++编程笔记:运算符重载丨重载C++中的New和Delete运算符

    new和delete运算符也可以像C ++中的其他运算符一样重载.New和Delete运算符可以全局重载,也可以在特定类中重载. (1)如果使用某个类的成员函数来重载这些运算符,则意味着这些运算符仅针 ...

  7. 【Groovy】集合遍历 ( 操作符重载 | 集合中的 “ << “ 操作符重载 | 使用集合中的 “ << “ 操作符添加一个元素 | 使用集合中的 “ << “ 操作符添加一个集合 )

    文章目录 一.集合中的 " << " 操作符重载 1.使用集合中的 " << " 操作符添加一个元素 2.使用集合中的 " & ...

  8. 【Groovy】集合遍历 ( 操作符重载 | 集合中的 “ + “ 操作符重载 | 集合中的 “ - “ 操作符重载 | 代码示例 )

    文章目录 一.集合中的 " + " 操作符重载 二.集合中的 " - " 操作符重载 三.完整代码示例 一.集合中的 " + " 操作符重载 ...

  9. C++中逗号操作符重载的分析

    1,关注逗号操作符重载后带来的变化: 2,逗号操作符: 1,逗号操作符(,)可以构成都好表达式:exp1, exp2, exp3, ..., expN 1,逗号表达式用于将多个表达式连接为一个表达式: ...

最新文章

  1. PAGER set to stdout_Python || 学习笔记(4):dictamp;amp;set
  2. 三星oneui主屏幕费电_都 9012 年了,三星系统还「负优化」吗?
  3. linux内核网络接收数据流程图【转】
  4. MyEclipse6.5安装SVN插件的方法--在线安装
  5. .NET Standard 2.0 特性介绍和使用指南
  6. lxml库的基本使用-etree解析html得到对象的不同方式-0233
  7. 北上广等一线城市 IT 岗位已接近饱和?
  8. 原生小程序和 mpvue对比(开发前)
  9. php 判断是否在线,关于判断用户是否在线的问题!!!
  10. mysql数据库编程第六章试题_2016计算机二级MySQL数据库试题及答案
  11. 计算机网络路由器的配置连接不上,路由器安装设置好后电脑还是不能上网解决办法...
  12. java wed的工作流程
  13. matlab计算可靠性过程,基于MATLAB的蒙特卡洛方法对可靠度的计算
  14. 人力资源管理专业知识与实务(初级)【7】
  15. 长城汽车携旗下哈弗、欧拉、长城皮卡及WEY登陆北京车展
  16. struts2从入门到精通
  17. uchar t 单片机C语言的注释是什么,uchar(单片机中uchar是什么意思)
  18. 微信小程序标题栏放logo 搜索框
  19. VMware虚拟机安装Windows11(无需设置TMP密码)
  20. HP LoadRunner

热门文章

  1. html任务清单源码,JavaScript jQuery 任务清单 ToDoList
  2. Cuboid特征提取算法
  3. 【控制】《多智能体系统一致性与复杂网络同步控制》郭凌老师-目录
  4. 2_指令集、体系架构、微架构
  5. 乐高积木搭建微型地球仪,lego微型地球仪搭建详细流程
  6. 手机单机游戏合集大概40个G
  7. 使用noode.js创建一个服务器
  8. ORA-04031:oracle无法分配共享内存
  9. 即使是一个技术人员,也需要知道沟通的重要性
  10. Unity C#单例模式的实现