当前位置:   article > 正文

C++拾遗--new delete 重载_::delete 重载

::delete 重载

                        C++拾遗--new delete 重载

前言

    new和delete是操作动态内存的一对操作。对它们重载可以对内存管理进行有效的定制。

正文

1.局部重载

特别针对某一类型,对new和delete进行重载,可以对该类型对象的动态创建实行监控。如下代码:

代码

  1. #include <iostream>
  2. using namespace std;
  3. class MyClass
  4. {
  5. public:
  6. MyClass()
  7. {
  8. cout << "MyClass()" << endl;
  9. }
  10. ~MyClass()
  11. {
  12. cout << "~MyClass()" << endl;
  13. }
  14. void *operator new(std::size_t size)
  15. {
  16. cout << "局部new call" << endl;
  17. void *mem = malloc(size);
  18. if (mem) //内存分配失败,则返回0
  19. return mem; //return malloc(size);
  20. else
  21. throw bad_alloc(); //内存分配失败,抛出异常
  22. }
  23. void operator delete(void *ptr)
  24. {
  25. cout << "局部delete call" << endl;
  26. //不为空,则调用free释放内存
  27. if (ptr)
  28. {
  29. free(ptr);
  30. }
  31. }
  32. };
  33. int main()
  34. {
  35. cout << "******局部new delete重载演示***by David***" << endl;
  36. MyClass *my = new MyClass;
  37. delete my;
  38. cin.get();
  39. return 0;
  40. }
运行



运行结果表明

表达式new整合了内存分配和构造函数。先调用malloc分配内存,然后调用指定类型并相匹配的构造函数初始化该段内存。

表达式delete整合了析构函数和内存释放。先调用类的析构函数释放资源,后调用free释放分配的内存。


代码二

下面一个例子提供了对内存分配进行监控的一种方法。

  1. #include <iostream>
  2. using namespace std;
  3. class MyClass
  4. {
  5. public:
  6. //count记录未释放的对象个数
  7. static int count;
  8. int a;
  9. MyClass()
  10. {
  11. cout << "MyClass()" << endl;
  12. count++;
  13. }
  14. ~MyClass()
  15. {
  16. cout << "~MyClass()" << endl;
  17. count--;
  18. }
  19. //new 局部重载
  20. void *operator new(size_t size)
  21. {
  22. cout << "局部new call" << endl;
  23. void *mem = malloc(size); //内存分配失败,则返回0
  24. if (mem)
  25. return malloc(size);
  26. else
  27. throw bad_alloc(); //内存分配失败,抛出异常
  28. }
  29. //new[] 局部重载
  30. void *operator new[](std::size_t size)
  31. {
  32. cout << "局部new[] call" << endl;
  33. void *mem = malloc(size); //内存分配失败,则返回0
  34. if (mem)
  35. return malloc(size);
  36. else
  37. throw bad_alloc(); //内存分配失败,抛出异常
  38. }
  39. //delete 局部重载
  40. void operator delete(void *ptr)
  41. {
  42. cout << "局部delete call" << endl;
  43. //不为空,则调用free释放内存
  44. if (ptr)
  45. {
  46. free(ptr);
  47. }
  48. }
  49. //delete[] 局部重载
  50. void operator delete[](void *ptr)
  51. {
  52. cout << "局部delete[] call" << endl;
  53. //ptr不为空,则调用free释放内存
  54. if (ptr)
  55. {
  56. free(ptr);
  57. }
  58. }
  59. };
  60. int MyClass::count = 0;
  61. int main()
  62. {
  63. cout << "******new delete 局部重载演示***by David***" << endl;
  64. cout << "起始MyClass::count = " << MyClass::count << endl;
  65. MyClass *my = new MyClass;
  66. delete my;
  67. cout << "-----------------" << endl;
  68. MyClass my1;
  69. cout << "-----------------" << endl;
  70. MyClass *mys = new MyClass[5];
  71. cout << "MyClass::count = " << MyClass::count << endl;
  72. delete[]mys;
  73. cout << "MyClass::count = " << MyClass::count << endl;
  74. cin.get();
  75. return 0;
  76. }
运行



2.全局重载

对全局的new和delete重载可以监控所有类型的内存分配。

  1. #include <iostream>
  2. #include <string>
  3. using namespace std;
  4. class MyClass
  5. {
  6. public:
  7. MyClass()
  8. {
  9. cout << "MyClass()" << endl;
  10. }
  11. ~MyClass()
  12. {
  13. cout << "~MyClass()" << endl;
  14. }
  15. void *operator new(std::size_t size)
  16. {
  17. cout << "MyClass::new重载" << endl;
  18. void *mem = malloc(size);
  19. if (mem)
  20. return mem;
  21. else
  22. throw bad_alloc();
  23. }
  24. void *operator new[](std::size_t size)
  25. {
  26. cout << "MyClass::new[]重载" << endl;
  27. void *mem = malloc(size);
  28. if (mem)
  29. return mem;
  30. else
  31. throw bad_alloc();
  32. }
  33. void operator delete(void *ptr)
  34. {
  35. cout << "MyClass::delete重载" << endl;
  36. if (ptr)
  37. {
  38. free(ptr);
  39. }
  40. }
  41. void operator delete[](void *ptr)
  42. {
  43. cout << "MyClass::delete[]重载" << endl;
  44. if (ptr)
  45. {
  46. free(ptr);
  47. }
  48. }
  49. };
  50. //全局new重载
  51. void *operator new(std::size_t size)
  52. {
  53. cout << "全局new重载" << endl;
  54. void *mem = malloc(size);
  55. if (mem)
  56. return mem;
  57. else
  58. throw bad_alloc();
  59. }
  60. //全局new[]重载
  61. void *operator new[](std::size_t size)
  62. {
  63. cout << "全局new[]重载" << endl;
  64. void *mem = malloc(size);
  65. if (mem)
  66. return mem;
  67. else
  68. throw bad_alloc();
  69. }
  70. //全局delete重载
  71. void operator delete(void *ptr)
  72. {
  73. cout << "全局delete重载" << endl;
  74. if (ptr)
  75. {
  76. free(ptr);
  77. }
  78. }
  79. //全局delete[]重载
  80. void operator delete[](void *ptr)
  81. {
  82. cout << "全局delete[]重载" << endl;
  83. if (ptr)
  84. {
  85. free(ptr);
  86. }
  87. }
  88. int main()
  89. {
  90. cout << "******全局/局部new和delete都进行重载***by David***" << endl;
  91. int *p = new int;
  92. delete p;
  93. cout << "-------------------" << endl;
  94. double *ds = new double[10];
  95. delete[]ds;
  96. cout << "-------------------" << endl;
  97. MyClass *my = new MyClass;
  98. delete my;
  99. cout << "-------------------" << endl;
  100. MyClass *mys = new MyClass[3];
  101. delete[]mys;
  102. cin.get();
  103. return 0;
  104. }
运行



如果类型重新定义了new 和 delete,则调用局部的,否则调用全局的。


细节

  • operator new或operator new[]的返回类型必须是void*。
  • operator delete或operator delete[]的返回类型必须是void。
  • 类中重载的new和delete都是隐式static的。若显式声明,也不会出错。
  • size_t就是unsigned int。当编译器调用operator new时,把存储指定类型对象所需的字节数传递给size_t的形参。当调用operator new[]时,就传递数组中所有元素的字节数。


编译器对operator new的扩展,更像如下这般:

  1. void *operator new(std::size_t size)
  2. {
  3. if (size == 0) size = 1;//对于size为0,也要保证返回唯一内存地址
  4. void *mem = nullptr;
  5. try
  6. {
  7. if (void *mem = malloc(size))
  8. {
  9. //调用默认的构造函数对分配的内存进行初始化
  10. mem = MyClass::MyClass(mem);
  11. }
  12. }
  13. catch (...)
  14. {
  15. throw;
  16. }
  17. return mem;
  18. }




本专栏目录

所有内容的目录




声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小桥流水78/article/detail/876148?site
推荐阅读
相关标签
  

闽ICP备14008679号