c++ [wrong]simple "Garbage Collector"
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
- #include "Ptr.h"
- #include <iostream>
- using namespace std;
- class Box
- {
- public:
- void dosomething() { cout << "Box dosomething" << endl; }
- Box() { cout << "Box cons" << endl; }
- ~Box() { cout << "Box des" << endl; }
- };
- Ptr<Box> global;
- Ptr<Box> func() {
- Ptr<Box> pb(new Box());
- return pb;
- }
- void call(Ptr<Box> ptr)
- {
- if(ptr)
- ptr->dosomething();
- else
- cout << "ptr is null" << endl;
- }
- int main()
- {
- Ptr<Box> p = func();
- p->dosomething();
- (*p).dosomething();
- Ptr<Box> p2 = p;
- call(p2);
- p2.reset();
- cout << "after p2.reset" << endl;
- global = p;
- p.reset();
- call(p);
- (*global).dosomething();
- global.reset();
- cout << "after global.reset" << endl;
- return ;
- }
Ptr.h
- #ifndef PTR_H
- #define PTR_H
- #include <cstddef>
- template <typename TYPE>
- class Ptr {
- public:
- void reset()
- {
- dec_use();
- }
- Ptr& operator=(const Ptr<TYPE> ©)
- {
- dec_use();
- obj = copy.obj;
- use_count = copy.use_count;
- if (use_count) ++*use_count;
- return *this;
- }
- TYPE* operator->() { return obj; }
- TYPE& operator*() { return *obj; }
- const TYPE* operator->() const { return obj; }
- const TYPE& operator*() const { return *obj; }
- operator bool() const { return (obj != NULL); }
- Ptr(): obj(NULL), use_count(NULL) {}
- Ptr(TYPE *obj_): obj(obj_), use_count(new int()) {}
- Ptr(const Ptr ©): obj(NULL), use_count(NULL)
- {
- obj = copy.obj;
- use_count = copy.use_count;
- if (use_count) ++*use_count;
- }
- ~Ptr()
- {
- dec_use();
- }
- private:
- void dec_use() // decrease use_count
- {
- if (use_count != NULL) {
- if( --*use_count == ) {
- delete obj;
- delete use_count;
- }
- obj = NULL;
- use_count = NULL;
- }
- }
- TYPE *obj; // the actual object
- int *use_count; // number of Ptr objects point to 'obj'
- };
- #endif // PTR_H
main3.cpp
- #include <memory>
- #include <iostream>
- using namespace std;
- class Box
- {
- public:
- void dosomething() { cout << "Box dosomething" << endl; }
- Box() { cout << "Box cons" << endl; }
- ~Box() { cout << "Box des" << endl; }
- };
- shared_ptr<Box> global;
- shared_ptr<Box> func() {
- shared_ptr<Box> pb(new Box());
- return pb;
- }
- void call(shared_ptr<Box> ptr)
- {
- if(ptr)
- ptr->dosomething();
- else
- cout << "ptr is null" << endl;
- }
- int main()
- {
- shared_ptr<Box> p = func();
- p->dosomething();
- (*p).dosomething();
- shared_ptr<Box> p2 = p;
- call(p2);
- p2.reset();
- cout << "after p2.reset" << endl;
- global = p;
- p.reset();
- call(p);
- (*global).dosomething();
- global.reset();
- cout << "after global.reset" << endl;
- return ;
- }
---------------------------------------- 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
- #include "MemMgr.h"
- #include <cstdlib>
- int main()
- {
- MemMgr *p = new MemMgr;
- free(p);
- return ;
- }
main.cpp
- #include "MemMgr.h"
- #include <iostream>
- using namespace std;
- class Box
- {
- public:
- void dosomething() { cout << "Box dosomething" << endl; }
- Box() { cout << "Box cons" << endl; }
- ~Box() { cout << "Box des" << endl; }
- };
- Ptr<Box> global;
- MemMgr mgr;
- Ptr<Box> func() {
- Ptr<Box> pb = mgr.regist(new Box());
- return pb;
- }
- int main()
- {
- Ptr<Box> p = func();
- p->dosomething();
- (*p).dosomething();
- Ptr<Box> p2 = p;
- p2->dosomething();
- cout << "end of main" << endl;
- global = p2;
- return ;
- }
MemMgr.h
- #ifndef MEMMGR_H
- #define MEMMGR_H
- #include <map>
- template <typename TYPE>
- class Ptr;
- /**
- MemMgr take the idea of Garbage Collector
- from the Java language. It's just much simple
- and limited.
- */
- class MemMgr
- {
- template <typename T> friend class Ptr;
- private:
- typedef unsigned long count;
- template <typename T> void login(T* ptr_obj);
- template <typename T> void logout(T* ptr_obj);
- std::map<void*, count> cmap;
- public:
- MemMgr();
- /**
- Client is responsible to ensure obj is in the heap,
- and make sure only use Ptr objects rather than ordinary
- pointers when manipulating objects managed by MemMgr.
- Otherwise the behavior of the MemMgr is undefined.
- If MemMgr is destroyed before any Ptr object managed
- by it, all Ptr objects managed by that MemMgr are corrupted
- and their behavior is undefined, which eventually leads to
- memory leak.
- So it's crucial to make sure MemMgr is not destroyed
- before ALL Ptr objects managed by it are destroyed.
- */
- template <typename T> Ptr<T> regist(T *obj);
- ~MemMgr();
- };
- /**
- Ptr acts like a reference in java.
- */
- template <typename TYPE>
- class Ptr {
- friend class MemMgr;
- public:
- Ptr& operator=(const Ptr<TYPE> ©)
- {
- if(copy) {
- logout();
- obj = copy.obj;
- mgr = copy.mgr;
- copy.mgr->login(&obj);
- } // else leaves obj and mgr NULL
- return *this;
- }
- TYPE* operator->() { return obj; }
- TYPE& operator*() { return *obj; }
- const TYPE* operator->() const { return obj; }
- const TYPE& operator*() const { return *obj; }
- operator bool() const { return ( (obj != NULL) && (mgr != NULL) ); }
- Ptr(): obj(NULL), mgr(NULL) {}
- Ptr(const Ptr ©): obj(NULL), mgr(NULL)
- {
- if(copy) {
- obj = copy.obj;
- mgr = copy.mgr;
- copy.mgr->login(obj);
- }
- }
- ~Ptr()
- {
- logout();
- }
- private:
- Ptr(TYPE *_obj, MemMgr *_mgr): obj(_obj), mgr(_mgr)
- {
- mgr->login(obj);
- }
- void logout() {
- if (*this) {
- mgr->logout(obj); obj = NULL; mgr = NULL;
- }
- }
- TYPE *obj;
- MemMgr *mgr;
- };
- template <typename T> Ptr<T> MemMgr::regist(T *obj)
- {
- return Ptr<T>(obj, this);
- }
- template <typename T>
- void MemMgr::login(T* ptr_obj)
- {
- std::map<void*, count>::iterator iter = cmap.find(ptr_obj);
- if (iter != cmap.end()) {
- ++(iter->second);
- } else {
- cmap.insert(std::pair<void*, count>(ptr_obj, ));
- }
- }
- template <typename T>
- void MemMgr::logout(T* ptr_obj)
- {
- std::map<void*, count>::iterator iter = cmap.find(ptr_obj);
- if (iter != cmap.end()) {
- --(iter->second);
- if (iter->second == ) {
- T *p = (T*)(iter->first);
- delete p;
- }
- }
- }
- #endif // MEMMGR_H
MemMgr.cpp
- #include "MemMgr.h"
- #include <iostream>
- using namespace std;
- MemMgr::MemMgr()
- {
- cout << "MemMgr cons" << endl;
- }
- MemMgr::~MemMgr()
- {
- cout << "MemMgr des" << endl;
- }
c++ [wrong]simple "Garbage Collector"的更多相关文章
- [GC]一个简单的Garbage Collector的实现
前言: 最近看了google的工程师写的一个非常简单的垃圾收集器,大概200多行C代码,感叹大牛总能够把复杂的东西通过很简单的语言和代码表达出来.为了增加自己的理解,决定把大牛的想法和代码分析一遍,与 ...
- 一个简单的Garbage Collector的实现
一个简单的Garbage Collector的实现 前言: 最近看了google的工程师写的一个非常简单的垃圾收集器,大概200多行C代码,感叹大牛总能够把复杂的东西通过很简单的语言和代码表达出来.为 ...
- AGC027 B - Garbage Collector 枚举/贪心
目录 题目链接 题解 代码 题目链接 AGC027 B - Garbage Collector 题解 对于一组选取组的最优方案为,走到一点,然后顺着路径往回取点 设选取点坐标升序为{a,b,c,d} ...
- 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 ...
- agc 027 B - Garbage Collector
B - Garbage Collector https://agc027.contest.atcoder.jp/tasks/agc027_b 题意: x坐标轴上n个垃圾,有一个机器人在从原点,要清扫垃 ...
- Getting Started with the G1 Garbage Collector(译)
原文链接:Getting Started with the G1 Garbage Collector 概述 目的 这篇教程包含了G1垃圾收集器使用和它如何与HotSpot JVM配合使用的基本知识.你 ...
- Erlang Garbage Collector
Erlang Garbage Collector | Erlang Solution blog https://www.erlang-solutions.com/blog/erlang-garbage ...
- 提交并发量的方法:Java GC tuning :Garbage collector
三色算法,高效率垃圾回收,jvm调优 Garbage collector:垃圾回收器 What garbage? 没有任何引用指向它的对象 JVM GC回收算法: 引用计数法(ReferenceCou ...
- 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
随机推荐
- JQuery中的动画(ppt)
<!DOCTYPE html> <html> <head> <title>test1.html</title> <meta http- ...
- iOS开发——随机数的使用
1).arc4random() 比较精确不需要生成随即种子 使用方法 : 通过arc4random() 获取0到x-1之间的整数的代码如下: ...
- Ado.Net基础拾遗二:插入,更新,删除数据
插入数据 public void InsertDataToSQL() { string conStr = ConfigurationManager.ConnectionStrings["No ...
- OS中处理机调度模型和调度算法
OS中处理机调度模型和调度算法 调度层次 1.1. 高级调度(长程调度,作业调度) 功能:依据某种算法.把在外存队列上处于后备队列的那些作业调入内存.以作业为操做对象. 作业:比程序更为广泛的概念,不 ...
- 【HTTPS双向加密认证】
HTTPS单向认证和双向认证 nearzk-osc 发布时间: 2015/07/30 15:27 阅读: 4177 收藏: 178 点赞: 6 评论: 3 一.背景&概念 HTTPS:在htt ...
- Shortest Path [3]
-----------应要求删除---------------
- 为Linux上FireFox安装Flash插件
废话少说,步骤如下: 1.点击网页上插件缺失处,根据提示下载tar.gz版本的插件,我下载的版本是install_flash_player_11_linux.i386.tar.gz,这个文件被下载到了 ...
- 倍福TwinCAT(贝福Beckhoff)常见问题(FAQ)-电机实际运行距离跟给定距离不一致怎么办,如何设置Scaling Factor
有时候,让电机从0度转到绝对的360度,有时候会出现电机实际转动更多或者更少的情况. 一般是电机的编码器的Scaling Factor Numerator数值不对导致的,数值越小,则同比转过角度越 ...
- WIN7怎样把屏幕改为16位色
1 右击桌面,选择屏幕分辨率 2 选择高级设置 3 点击"监视器"选项卡,把颜色改为16位. 4 屏幕会暂时黑屏一段时间,随后主题将自动切换为基础版(失去Areo效果) ...
- mysql 5.6 修改root原始密码不为空方法
mysql 5.6安装好之后,是默认root用户的密码为空的,此时为了安全性需要修改密码不为空,修改方法为: cmd或者mysql 5.6 command line client登陆之后,输入一下命令 ...