修破门 的个人资料修破门之界照片日志列表更多 ![]() | 帮助 |
|
2007/10/28 用C++实现带引用计数并且线程安全的智能指针仔细想一下要做一个和boost里的share_ptr类似的带引用计数的智能指针也不是太难,今天下午花了点时间写了一个,支持多线程。 namespace XPtr {
//引用计数模板对象,L 表示所使用的同步对象类型,用作引用计数增减时做同步操作 template<typename L> class RefCounter { private: int counter; L _lock; //同步对象操作辅助类,构造函数中加锁,析构函数中解锁 class LockHelper { private: L _l; public: LockHelper(L &l) { _l = l; _l.lock(); } ~LockHelper() { _l.unlock(); } };
public: RefCounter():counter(0) { } //整形转换操作符 operator int() { return counter; } // int operator++() { LockHelper l(_lock); return ++counter; } // int operator--() { LockHelper l(_lock); return --counter; } };
//单线程时的同步对象,全部为空,不做线程同步
struct SingleThread {
void lock() {};
void unlock() {};
}; //主角登场,智能指针模板, T 为指针指向内容,ThreadLock为线程同步策略类,默认为单线程
private: T * m_ptr; //引用计数类的指针,指向同一个指针的智能指针要共同维护一个引用计数类实例 RefCounter<ThreadLock> *m_pCounter;
public: //智能指针可以不初始化,待以后赋值 xptr():m_ptr(0),m_pCounter(0) {}
//用另一个typename P而不直接用T,这样可以支持用子类的指针类初始化父类智能指针 //使用explicit关键字,表示禁止隐式类型转换,防止无意识的情况下把已有的原生指针转成智能指针 template<typename P> explicit xptr(P *p) { create( new RefCounter<ThreadLock>(), p); } //拷贝构造函数,若需要支持用子类的智能指针初始化,则需要另外申明一个模板拷贝构造函数,增加一个typename P,类似前面的构造函数 //但由于需要改变引用计数,所以需要智能指针开放接口以取得引用计数对象和原始指针对象,这样会不太雅观,所以这里有个tradeoff (见肥浩的留言) xptr(const xptr<T> &p) { create(p.m_pCounter,p.m_ptr); } //赋值操作,同上 const xptr<T>& operator= (const xptr<T> &p) { if(&p != this) { destory(); create(p.m_pCounter, p.m_ptr); } return *this ; } //析构函数,调用destory()辅助函数,用以减少引用计数,并适时销毁原始指针对象和引用计数对象 ~xptr() { destory();} T* operator->() const{ return m_ptr;}
//布尔值转换操作符,判断是否为空 operator bool() { return m_ptr!=0 ; } private: //辅助函数,用以增加引用计数,取得原始指针对象和引用计数对象 template<typename P> void create(RefCounter<ThreadLock> * pf , P* pp) { m_pCounter = pf;
if(m_pCounter!=0) ++*m_pCounter; m_ptr = pp; } //辅助函数,用以减少引用计数,为零时销毁原始指针对象和引用计数对象 void destory() { //在多线程环境下这里看似会有同步问题,但是那种情况是不会发生的,所以这样是安全的 if(m_pCounter!=0 && --*m_pCounter==0) { delete m_pCounter; delete m_ptr; } } };
} 要用在多线程环境中的话需要根据平台实现一个同步类,内部有一个mutex,支持lock, unlock操作,使用时将此同步类作为智能指针的第二个模板参数即可。 2007/10/13 站在巨人的脚后跟上 最近发生了很多事情,很久没有心思更新blog了。有句话说的好:“出来混迟早要还的”。人要为自己犯的错误或失误付出代价,不管这代价是否公平合理。世界上本来也就没有什么公平可言,付出不一定就能有收获,努力不一定就能成功,坏人不一定会遭到惩罚,好人不一定会有好报。这个道理我很久以前就明白了,这一次再次证实。或许人们对公平的定义不同,你认为不公平的事别人会认为很公平,很难说得清的。就当成是生活中的又一个小坎坷吧,也见多了。特别欣慰的是有朋友看到我MSN签名异常来询问安慰,让我感觉好多了。
言归正传,现在说说长期的困惑,转眼间在新公司又呆了一年了,回顾这一年来,觉得很空虚,不知道自己到底做了些什么有意义的东西,技术上往好了说是几乎没有什么长进,曾经引以为豪的C++现在也是一塌糊涂,毕竟一年没用了!现在用的Java虽说用了一年,可是实际编码时间很少,也就是半瓶子醋水平,和不会没有什么太大的区别,更不用说和自己的C++相比了。不客气地说,整个team这一年来做的东西充其量只相当于三流小公司三个月做出的一个prototype,看上去更像一个玩具(?)而不是什么像样的产品,我实在想不出来里面究竟有些什么技术含量。直到前不久,形势还在瞬息万变,今天说这么做,明天说那么做,今天说做这个,明天说做那个,到底有谱没谱?把所有可能的平台和所有语言都用一用,J2ME, WM, Symbian, C++, C#, Java...,好吧这个只是顺便提提,如果只是没谱的话也还好说,毕竟不是天天没谱。
当不了巨人的左膀右臂,也站不到巨人的肩膀上,我们只能站在巨人的脚后跟上(怎么站?不好站吧?所以才瞬息万变经常没谱被人牵着鼻子走啊),在自己的三分地上闭门造车,精通木工活的人被派去打铁,精通铁匠活的被派去做木工,拼凑一些不知所谓的玩意,忙着加班却不知道自己在做些什么,也不知道现在做的东西对自己以后的发展有什么帮助。这难道真的是我曾经梦想中的工作吗?还是我太不知足了?
为了混口饭吃,又能有什么办法呢?
|
|
|