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> &copy)
{
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 &copy): 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> &copy)
{
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 &copy): 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"的更多相关文章

  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. [HDU6271]Master of Connected Component

    [HDU6271]Master of Connected Component 题目大意: 给出两棵\(n(n\le10000)\)个结点的以\(1\)为根的树\(T_a,T_b\),和一个拥有\(m( ...

  2. scope的范围

    (一)scope=“singleton” 知识点:无论获取多少个bean,得到的总是一样的地址,singleton范围下只会创建一个bean实例 1.Bean4.java package com.in ...

  3. 动态OSPF配置路由表

    动态ospf设置路由表 以Rourer1为例子 (1)首先设置路由器端口ip Router(config)#inter f0/0 Router(config-if)#ip add 192.168.1. ...

  4. iOS使用CoreData实现收藏功能

    一般做收藏都是使用数据库或者归档,使用CoreData实现收藏功能就是没事时练一下,实现大概和数据库差不多. 首先创建一个工具类继承NSObject,在里面实现所需要的方法. 工具类的.h文件: ty ...

  5. dwz中弹出的窗口页面如何获取前页面(点击按钮的页面)的元素???

    在页面A.jsp中点击一个按钮,使用$.pdialog.open()方法弹出b.jsp页面(对话框窗口),我要在b.jsp中选中值然后关闭窗口(b.jsp)返回值给A.jsp~ =========== ...

  6. VB6的UTF8编码解码

    'UTF-8编码  Public Function UTF8Encode(ByVal szInput As String) As String     Dim wch  As String     D ...

  7. 【AS3 Coder】任务六:人物换装(纸娃娃)系统的制作

    使用框架:AS3(Flash Professional CS5.0及更高版本 + Flash Buider)任务描述:了解人物换装系统的制作原理难度系数:2 本章源码下载:http://www.iam ...

  8. xubuntu openocd nRF51822 download --- 2

    昨天非常晚的时候才最终发现事实上Unkown USB Device并非错误,仅仅是个警告而已,所以我们不关心就能够.让Makefile继续往下走就能够.于是我尝试mbs,s110.cload和firm ...

  9. hexo 使用教程

    hexo 使用教程 这个早就用起来了,写给需要的小伙伴 mayufo.github.io 先扔出自己的地址 安装 想玩hexo,需要安装以下应用 git node 安装完成在终端输入 $ npm in ...

  10. ThreadLocal的简单使用(读书笔记)

         从ThreadLocal的名字上可以看到,这是一个线程局部变量,也就是说,只有当前线程可以访问,既然是只有当前线程可以访问的数据,自然是线程安全的. public class ThreadL ...