In fact, Ptr alone can accomplish the task mentioned below.

Implementation see Ptr.h, main2.cpp. In C++11, we also have a better choice: std::shared_ptr (as you can see in main3.cpp).

main2.cpp

  1. #include "Ptr.h"
  2.  
  3. #include <iostream>
  4.  
  5. using namespace std;
  6.  
  7. class Box
  8. {
  9. public:
  10. void dosomething() { cout << "Box dosomething" << endl; }
  11. Box() { cout << "Box cons" << endl; }
  12. ~Box() { cout << "Box des" << endl; }
  13. };
  14.  
  15. Ptr<Box> global;
  16.  
  17. Ptr<Box> func() {
  18. Ptr<Box> pb(new Box());
  19. return pb;
  20. }
  21.  
  22. void call(Ptr<Box> ptr)
  23. {
  24. if(ptr)
  25. ptr->dosomething();
  26. else
  27. cout << "ptr is null" << endl;
  28. }
  29.  
  30. int main()
  31. {
  32. Ptr<Box> p = func();
  33. p->dosomething();
  34. (*p).dosomething();
  35. Ptr<Box> p2 = p;
  36. call(p2);
  37. p2.reset();
  38. cout << "after p2.reset" << endl;
  39. global = p;
  40. p.reset();
  41. call(p);
  42. (*global).dosomething();
  43. global.reset();
  44. cout << "after global.reset" << endl;
  45. return ;
  46. }

Ptr.h

  1. #ifndef PTR_H
  2. #define PTR_H
  3.  
  4. #include <cstddef>
  5.  
  6. template <typename TYPE>
  7. class Ptr {
  8.  
  9. public:
  10. void reset()
  11. {
  12. dec_use();
  13. }
  14. Ptr& operator=(const Ptr<TYPE> &copy)
  15. {
  16. dec_use();
  17. obj = copy.obj;
  18. use_count = copy.use_count;
  19. if (use_count) ++*use_count;
  20. return *this;
  21. }
  22. TYPE* operator->() { return obj; }
  23. TYPE& operator*() { return *obj; }
  24. const TYPE* operator->() const { return obj; }
  25. const TYPE& operator*() const { return *obj; }
  26. operator bool() const { return (obj != NULL); }
  27.  
  28. Ptr(): obj(NULL), use_count(NULL) {}
  29. Ptr(TYPE *obj_): obj(obj_), use_count(new int()) {}
  30. Ptr(const Ptr &copy): obj(NULL), use_count(NULL)
  31. {
  32. obj = copy.obj;
  33. use_count = copy.use_count;
  34. if (use_count) ++*use_count;
  35. }
  36. ~Ptr()
  37. {
  38. dec_use();
  39. }
  40. private:
  41. void dec_use() // decrease use_count
  42. {
  43. if (use_count != NULL) {
  44. if( --*use_count == ) {
  45. delete obj;
  46. delete use_count;
  47. }
  48. obj = NULL;
  49. use_count = NULL;
  50. }
  51. }
  52. TYPE *obj; // the actual object
  53. int *use_count; // number of Ptr objects point to 'obj'
  54. };
  55.  
  56. #endif // PTR_H

main3.cpp

  1. #include <memory>
  2.  
  3. #include <iostream>
  4.  
  5. using namespace std;
  6.  
  7. class Box
  8. {
  9. public:
  10. void dosomething() { cout << "Box dosomething" << endl; }
  11. Box() { cout << "Box cons" << endl; }
  12. ~Box() { cout << "Box des" << endl; }
  13. };
  14.  
  15. shared_ptr<Box> global;
  16.  
  17. shared_ptr<Box> func() {
  18. shared_ptr<Box> pb(new Box());
  19. return pb;
  20. }
  21.  
  22. void call(shared_ptr<Box> ptr)
  23. {
  24. if(ptr)
  25. ptr->dosomething();
  26. else
  27. cout << "ptr is null" << endl;
  28. }
  29.  
  30. int main()
  31. {
  32. shared_ptr<Box> p = func();
  33. p->dosomething();
  34. (*p).dosomething();
  35. shared_ptr<Box> p2 = p;
  36. call(p2);
  37. p2.reset();
  38. cout << "after p2.reset" << endl;
  39. global = p;
  40. p.reset();
  41. call(p);
  42. (*global).dosomething();
  43. global.reset();
  44. cout << "after global.reset" << endl;
  45. return ;
  46. }

---------------------------------------- stupidest iead I've ever seen -----------------------------------------

|                                                                                                                                                         |

|                                                                                                                                                         |

The idea is to create a Ptr type that acts like a reference in Java.

And A Garbage Collector (MemMgr) type that acts like a garbage collector in Java.

Just a toy. :D

Question: why not delete all memory fragments managed by MemMgr in its destructor?

Answer: If you want to delete a piece of memory, you must cast the void* pointer to the exact type of that memory. However, there's no way for a MemMgr to know the type of the memory pieces, because type information is not managed by MemMgr. And you can't use the free function from <cstdlib>. For example, if you write "MemMgr *p = new MemMgr; free(p);" you'll find that the destructor of MemMgr is not called. And As shown in "test.cpp". "free" only works in pair with "malloc" or "realloc" etc functions in <cstdlib>. "delete" should work in pair with "new".

see this question: http://stackoverflow.com/questions/1518711/how-does-free-know-how-much-to-free

test.cpp

  1. #include "MemMgr.h"
  2. #include <cstdlib>
  3.  
  4. int main()
  5. {
  6. MemMgr *p = new MemMgr;
  7. free(p);
  8. return ;
  9. }

main.cpp

  1. #include "MemMgr.h"
  2.  
  3. #include <iostream>
  4.  
  5. using namespace std;
  6.  
  7. class Box
  8. {
  9. public:
  10. void dosomething() { cout << "Box dosomething" << endl; }
  11. Box() { cout << "Box cons" << endl; }
  12. ~Box() { cout << "Box des" << endl; }
  13. };
  14.  
  15. Ptr<Box> global;
  16. MemMgr mgr;
  17.  
  18. Ptr<Box> func() {
  19. Ptr<Box> pb = mgr.regist(new Box());
  20. return pb;
  21. }
  22.  
  23. int main()
  24. {
  25. Ptr<Box> p = func();
  26. p->dosomething();
  27. (*p).dosomething();
  28. Ptr<Box> p2 = p;
  29. p2->dosomething();
  30. cout << "end of main" << endl;
  31. global = p2;
  32. return ;
  33. }

MemMgr.h

  1. #ifndef MEMMGR_H
  2. #define MEMMGR_H
  3.  
  4. #include <map>
  5.  
  6. template <typename TYPE>
  7. class Ptr;
  8.  
  9. /**
  10. MemMgr take the idea of Garbage Collector
  11. from the Java language. It's just much simple
  12. and limited.
  13. */
  14. class MemMgr
  15. {
  16. template <typename T> friend class Ptr;
  17. private:
  18. typedef unsigned long count;
  19. template <typename T> void login(T* ptr_obj);
  20. template <typename T> void logout(T* ptr_obj);
  21. std::map<void*, count> cmap;
  22. public:
  23. MemMgr();
  24. /**
  25. Client is responsible to ensure obj is in the heap,
  26. and make sure only use Ptr objects rather than ordinary
  27. pointers when manipulating objects managed by MemMgr.
  28.  
  29. Otherwise the behavior of the MemMgr is undefined.
  30.  
  31. If MemMgr is destroyed before any Ptr object managed
  32. by it, all Ptr objects managed by that MemMgr are corrupted
  33. and their behavior is undefined, which eventually leads to
  34. memory leak.
  35.  
  36. So it's crucial to make sure MemMgr is not destroyed
  37. before ALL Ptr objects managed by it are destroyed.
  38. */
  39. template <typename T> Ptr<T> regist(T *obj);
  40. ~MemMgr();
  41.  
  42. };
  43.  
  44. /**
  45. Ptr acts like a reference in java.
  46. */
  47. template <typename TYPE>
  48. class Ptr {
  49.  
  50. friend class MemMgr;
  51.  
  52. public:
  53. Ptr& operator=(const Ptr<TYPE> &copy)
  54. {
  55. if(copy) {
  56. logout();
  57. obj = copy.obj;
  58. mgr = copy.mgr;
  59. copy.mgr->login(&obj);
  60. } // else leaves obj and mgr NULL
  61. return *this;
  62. }
  63. TYPE* operator->() { return obj; }
  64. TYPE& operator*() { return *obj; }
  65. const TYPE* operator->() const { return obj; }
  66. const TYPE& operator*() const { return *obj; }
  67. operator bool() const { return ( (obj != NULL) && (mgr != NULL) ); }
  68.  
  69. Ptr(): obj(NULL), mgr(NULL) {}
  70. Ptr(const Ptr &copy): obj(NULL), mgr(NULL)
  71. {
  72. if(copy) {
  73. obj = copy.obj;
  74. mgr = copy.mgr;
  75. copy.mgr->login(obj);
  76. }
  77. }
  78. ~Ptr()
  79. {
  80. logout();
  81. }
  82. private:
  83. Ptr(TYPE *_obj, MemMgr *_mgr): obj(_obj), mgr(_mgr)
  84. {
  85. mgr->login(obj);
  86. }
  87. void logout() {
  88. if (*this) {
  89. mgr->logout(obj); obj = NULL; mgr = NULL;
  90. }
  91. }
  92. TYPE *obj;
  93. MemMgr *mgr;
  94. };
  95.  
  96. template <typename T> Ptr<T> MemMgr::regist(T *obj)
  97. {
  98. return Ptr<T>(obj, this);
  99. }
  100.  
  101. template <typename T>
  102. void MemMgr::login(T* ptr_obj)
  103. {
  104. std::map<void*, count>::iterator iter = cmap.find(ptr_obj);
  105. if (iter != cmap.end()) {
  106. ++(iter->second);
  107. } else {
  108. cmap.insert(std::pair<void*, count>(ptr_obj, ));
  109. }
  110. }
  111.  
  112. template <typename T>
  113. void MemMgr::logout(T* ptr_obj)
  114. {
  115. std::map<void*, count>::iterator iter = cmap.find(ptr_obj);
  116. if (iter != cmap.end()) {
  117. --(iter->second);
  118. if (iter->second == ) {
  119. T *p = (T*)(iter->first);
  120. delete p;
  121. }
  122. }
  123. }
  124.  
  125. #endif // MEMMGR_H

MemMgr.cpp

  1. #include "MemMgr.h"
  2.  
  3. #include <iostream>
  4.  
  5. using namespace std;
  6.  
  7. MemMgr::MemMgr()
  8. {
  9. cout << "MemMgr cons" << endl;
  10. }
  11.  
  12. MemMgr::~MemMgr()
  13. {
  14. cout << "MemMgr des" << endl;
  15. }

c++ [wrong]simple "Garbage Collector"的更多相关文章

  1. [GC]一个简单的Garbage Collector的实现

    前言: 最近看了google的工程师写的一个非常简单的垃圾收集器,大概200多行C代码,感叹大牛总能够把复杂的东西通过很简单的语言和代码表达出来.为了增加自己的理解,决定把大牛的想法和代码分析一遍,与 ...

  2. 一个简单的Garbage Collector的实现

    一个简单的Garbage Collector的实现 前言: 最近看了google的工程师写的一个非常简单的垃圾收集器,大概200多行C代码,感叹大牛总能够把复杂的东西通过很简单的语言和代码表达出来.为 ...

  3. AGC027 B - Garbage Collector 枚举/贪心

    目录 题目链接 题解 代码 题目链接 AGC027 B - Garbage Collector 题解 对于一组选取组的最优方案为,走到一点,然后顺着路径往回取点 设选取点坐标升序为{a,b,c,d} ...

  4. New Garbage Collector http://wiki.luajit.org/New-Garbage-Collector

    New Garbage Collector http://wiki.luajit.org/New-Garbage-Collector GC Algorithms This is a short ove ...

  5. agc 027 B - Garbage Collector

    B - Garbage Collector https://agc027.contest.atcoder.jp/tasks/agc027_b 题意: x坐标轴上n个垃圾,有一个机器人在从原点,要清扫垃 ...

  6. Getting Started with the G1 Garbage Collector(译)

    原文链接:Getting Started with the G1 Garbage Collector 概述 目的 这篇教程包含了G1垃圾收集器使用和它如何与HotSpot JVM配合使用的基本知识.你 ...

  7. Erlang Garbage Collector

    Erlang Garbage Collector | Erlang Solution blog https://www.erlang-solutions.com/blog/erlang-garbage ...

  8. 提交并发量的方法:Java GC tuning :Garbage collector

    三色算法,高效率垃圾回收,jvm调优 Garbage collector:垃圾回收器 What garbage? 没有任何引用指向它的对象 JVM GC回收算法: 引用计数法(ReferenceCou ...

  9. The Go Blog Getting to Go: The Journey of Go's Garbage Collector

    Getting to Go: The Journey of Go's Garbage Collector https://blog.golang.org/ismmkeynote

随机推荐

  1. JQuery中的动画(ppt)

    <!DOCTYPE html> <html> <head> <title>test1.html</title> <meta http- ...

  2. iOS开发——随机数的使用

    1).arc4random() 比较精确不需要生成随即种子        使用方法 :                  通过arc4random() 获取0到x-1之间的整数的代码如下:       ...

  3. Ado.Net基础拾遗二:插入,更新,删除数据

    插入数据 public void InsertDataToSQL() { string conStr = ConfigurationManager.ConnectionStrings["No ...

  4. OS中处理机调度模型和调度算法

    OS中处理机调度模型和调度算法 调度层次 1.1. 高级调度(长程调度,作业调度) 功能:依据某种算法.把在外存队列上处于后备队列的那些作业调入内存.以作业为操做对象. 作业:比程序更为广泛的概念,不 ...

  5. 【HTTPS双向加密认证】

    HTTPS单向认证和双向认证 nearzk-osc 发布时间: 2015/07/30 15:27 阅读: 4177 收藏: 178 点赞: 6 评论: 3 一.背景&概念 HTTPS:在htt ...

  6. Shortest Path [3]

    -----------应要求删除---------------

  7. 为Linux上FireFox安装Flash插件

    废话少说,步骤如下: 1.点击网页上插件缺失处,根据提示下载tar.gz版本的插件,我下载的版本是install_flash_player_11_linux.i386.tar.gz,这个文件被下载到了 ...

  8. 倍福TwinCAT(贝福Beckhoff)常见问题(FAQ)-电机实际运行距离跟给定距离不一致怎么办,如何设置Scaling Factor

    有时候,让电机从0度转到绝对的360度,有时候会出现电机实际转动更多或者更少的情况.   一般是电机的编码器的Scaling Factor Numerator数值不对导致的,数值越小,则同比转过角度越 ...

  9. WIN7怎样把屏幕改为16位色

    1 右击桌面,选择屏幕分辨率   2 选择高级设置   3 点击"监视器"选项卡,把颜色改为16位.   4 屏幕会暂时黑屏一段时间,随后主题将自动切换为基础版(失去Areo效果) ...

  10. mysql 5.6 修改root原始密码不为空方法

    mysql 5.6安装好之后,是默认root用户的密码为空的,此时为了安全性需要修改密码不为空,修改方法为: cmd或者mysql 5.6 command line client登陆之后,输入一下命令 ...