GEM4上已经有了,很不错的一套实现。
基于Java垃圾管理机制的程序,基本不需要考虑资源的删除问题,但是C++程序员经常恼火的就是资源的问题。
普通的资源系统的做法,如果像OGRE那样,很多人已经觉得很酷了,但是我总觉得OGRE的资源系统反倒是写的最糟糕的一套系统。到1.0发布版本的前一个版本为止,资源系统仍然有些逻辑没有写完,包括多资源动态调入调出,可能OGRE社群还没遇到像WOW这样动辄数个GB的资源的应用。
在动态调入调出前,需要解决的一个问题,就是明确哪些资源可以调出,再说明白些,就是哪些资源目前没有被使用?
这个问题,COM可以解答,就是“标准的”AddRef、Release机制,但这个机制有一个臭名昭著的问题,就是迫使每个人在进行指针赋值的时候都必须自己自觉地加一个AddRef,指针销毁的时候,都用Release销毁。
例如:
RESOURCE * pRes = GetResMgr()->GetRes("sth");
这是绝对没问题的,sth会被Addref。
但是,您防不住:
RESOURCE * pRes2 = pRes;
而这时候,如果pRes2没有被手动AddRef,哼哼哼哼……
难道COM的开发者以为共产主义社会已经来临了?自觉?搞笑吧,只要有一个人不自觉,他就会很郁闷。他的郁闷会进而转化为使用他写的程序的人的郁闷。再进而转化为这个人所在公司的郁闷:人们会向这个公司的油箱里塞入成千上万谩骂、威胁的信笺……或许还有通知“法庭上见”的律师函。
如果您开发的是一个引擎,千万不要认为使用引擎的人都是牛人,都是自觉的人。就像当您开发一个游戏的时候,千万不要以为游戏的使用者都是中规中矩的玩家,他们有时候经常会做一些在您眼里奇怪的事情,如果这时候,游戏挂了,您觉得这个错误该让谁来买单呢?让玩家吗?
可以,但是您将因此失去一个玩家,或者,如果这个人是某个BBS的牛人,您将因此失去整个某BBS的人,然后一传十十传百……
请一定要记住一句话:“舆论的最大优势是在于它杀死一个人是如此的高效,而却不必为此承担任何法律责任”。谁说的?……我。
言归正转,看看我们要做的事情:我们肯定不能避免指针对指针的赋值,这是前提;我们不想让人们在这种时候都去记住调一个AddRef,怎么办呢?
学习一下Windows吧,高明的Windows在管理内核对象的时候,用的是什么?恩,对了,Handle。
在C++中,Handle是一个void*指针,无论是HWND、HINSTANCE还是别的,都是一个typedef void* HXX,但是我想我们没必要这么笨的。
我们的Handle可能类似于下面的样子:
class Handle
{
...
public:
RESOURCE* ptr;
...
};
没甚么啊,您会说,就是一层包装而以。
对,但是包装后我们就可以做很多事情了哦~,比如说在包装上打上商店的商标,呵呵,人们就可以免费为我们做广告了。
我们可以重载拷贝构造子和赋值号,而在构造子、拷贝构造子中、赋值号中,我们可以:
ptr->AddRef()
同理,Handle销毁的时候:
ptr->Release()
这回就算有人能把自己的老婆都忘掉,他也绝对忘不掉去调用AddRef了,虽然他自己都不知道这个AddRef是在哪里调用的。
但您必须保证,在资源系统,以及任何用到这些资源的地方,都只使用Handle,不过我想这应该很容易。
如果还不明白,就去看《游戏编程精粹4》吧,80快钱,不过您不用买,只需要去看中间那个章节就可以了,好像是什么什么“弱引用”什么什么来着。
发表于 @ 2005年10月23日 16:50:00|评论(loading...)|编辑