noslopforever [天堂里的死神]

我浴血奋战,只为了神圣永久不变的传言

用户操作
[即时聊天] [发私信] [加为好友]
noslopforever(天堂里的死神)ID:noslopforever
76262次访问,排名1397,好友5人,关注者13人。
3D、图形学、游戏、哲学、历史、音乐,一个都不能少。
noslopforever的文章
原创 85 篇
翻译 2 篇
转载 4 篇
评论 215 篇
noslopforever(天堂里的死神)的公告

-欢迎大家来到我的空间。这里关注游戏相关学科的问题。
-自我介绍:男,25岁,程序员,喜欢战争、历史和哲学题材游戏。作为一位普通的初学者,希望众位前辈们能多多包涵和帮助。
-欢迎大家拍砖。本Blog原创的文章,如要转载,请注明出处和姓名。本Blog放置的代码,大部分是伪码,不保证能够运行。
*留言本1:没有CSDN帐号的网友留言请点击此链接
*留言本2:CSDN网友请在个人空间留言 ^_^




烽火过千年,往事如烟。争斗一生归何处?黄土青山。 繁华总易逝,回首不堪。敢叫天地换新颜,铁马连天。 ——《无题》 李巍于2008年6月9日

-最近在做:做好自己的项目,安排自己的时间。

-有些栏目的文章是不放在主页显示的,如果有感兴趣的可以到相应栏目查询。杂项和Just As Gamer栏目的,仅作为个人喜好,恕不回复。

最近评论
RAINini:比我小一岁,比我厉害这么多,心里不平衡,请我吃饭。
RAINini:createDirectory好像不支持递归创建目录,../temp/temp 就创建失败了。
noslopforever:嘿嘿……奔三啦……
版本结束,再去酸菜鱼吧~~嘴馋了~~^o^
noslopforever:好的,多谢 ^_^,我马上去弄个1.36来
Nhsoft:你装啥老啊。藕都28了,faint.....竟然比我小三岁,快请客。
文章分类
收藏
相册
misc杂项
朝圣者的路途
文档所需图片册
我的书单
我的照片
!飞龙在天!
cproom前辈的Blog
eXtreme 3D —— Dreams的Blog(RSS)
flymemory的Blog
johnson的Blog——我的老师和第一个上司 ^_^
nhsoft——野猪大大的Blog
Nightmare of Design/Dev(RSS)
游戏编程实践——我的老师的Blog
马肝前辈的Blog
!虎狼成群!
亮——同学、引擎程序员
江自流——另一位同学兼才思敏捷的策划
游戏王——同学,一位才思敏捷的策划
推荐网页
Boost——C++准标准库
Boost中文站
GameDev.net
OGRE3D中文站
OGRE3D——开源的3D图形引擎
Sourceforge
有关WOW格式的Wiki
涂鸦软件——一个很牛的国产游戏引擎
喜欢的站点
《闪电战》杂志讨论区
帝国之鹰
德军总部
英雄世界
存档
软件项目交易
订阅我的博客
XML聚合  FeedSky
订阅到鲜果
订阅到Google
订阅到抓虾
订阅到BlogLines
订阅到Yahoo
订阅到GouGou
订阅到飞鸽
订阅到Rojo
订阅到newsgator
订阅到netvibes

原创 SharePtr非侵入版本收藏

新一篇: 英雄连1V1战胜专家电脑! | 旧一篇: 实现纹理Blend编辑功能,发图。

【李巍(noslopforever·天堂里的死神)原作,转载请注明出处】

本Blog原来那篇《智能指针三兄弟》:

http://blog.csdn.net/noslopforever/archive/2006/12/19/1449569.aspx

,在智能指针的使用上,使用了侵入式的设计。欲使用智能指针,则必须为每个使用智能指针的类生成一个static的INVALID对象。如果是自己写一个库自己用那大凡没有问题,但如果用在别人的库上,这就吃亏了。

INVLALID对象的主要作用是:在解引用(*),指向(->)等操作发生的时候,当智能指针发现自己所接管的指针是一个NULL,就会把指针重定位到INVALID对象上去。以防用户既不写try(比如像我这样的“异常无视流”的坚定支持者: P。题外话,如果要是一个try的坚定支持者的话,那么Boost的智能指针库就很好用了,剩下的内容您就不用看了 ^_^ ),又不判断指针合法与否而导致程序挂掉。现在不让你挂了,只是满天遍地给你报日志,告诉你引用了某某某非法对象。

对于一个抽象或者非抽象类,INVALID类往往应从它们派生,并删除其主要操作函数的实现,转而仅输出Log后就返回错误值。如果您对用户的C++功底放心,那么也可以选择throw一个异常,这对这些用户也是一个好处——异常多了他们自己就记住该怎么去try catch了。助人为乐,帮人学习,此乃功德无量,功德无量……(众人:扔砖!)

INVALID类和对象应有如下特征:

INVALID对象有且仅有一个,且应以实例方式创建自INVALID类。因为INVALID对象多了也没用,一个就够了。

INVALID类的AddRef和Release方法应该架空。在这套体系下,用户很可能会继续无视指针是否合法(因为现在不合法已经不会让他们的程序挂掉了),因此更可能会误调用INVALID对象的Release和Addref。Addref还好,但Release在很多人写起来往往就是if(--ref == 0) delete this;这种情况自然导致对一个唯一的、在桟上创建(而不是在堆上创建)、而且还到处被引用的对象的delete操作,接下来的结果——上帝对我说:“那就不是你我能知道的了”……

重新说一下INVALID,下面开始本帖想说的主题:

昨天散步的时候想到,关于类和INVALID类,是一一对应的,其实可以把他看作一个类和一个INVALID类组成了一个Pair,这意味着什么呢?如何在编译期实现Pair,你想起来了么?

传说中的Traits!

(下面的代码按照记忆所写,可能语法过不去……)

template<typename T>

struct InvalidClassTraits {

    typedef void NULL_CLASS;

};

这里,void的原因很简单,void是一个非常特殊的类型,这个类型无法在堆和桟上进行实例化。

而如果我们要建立一个Pair,就这么写:

template<> struct InvalidClassTraits<ClassA>

{ typedef Null_ClassA NULL_CLASS } ;

这里,ClassA和Null_ClassA是原始类和INVALID类。

用的时候怎么用呢?

下面:

template<typename T>

struct _Invalid {

    typedef T ValueType;

    static ValueType* ReturnInvalid()

    {

        static InvalidClassTraits<T>::NULL_CLASS NullObj;   // 注意这一句

        return &NullObj;

    }

};

这就满足了我们return一个INVALID对象指针的要求了,而且这个INVALID对象,来自于桟,而且唯一。

原来代码里 return T::INVALID;现在就应该换成:return _Invalid<T>::ReturnInvalid();了。

 

放到工程里,现在的做法是:

.h里:

class A{

virtual void do() = 0;

};

class A_NULL{

void do();

};

template<> struct InvalidClassTraits<A>{ typedef A_NULL NULL_CLASS } ;

cpp里:

void A_NULL::do()

{

   // throw ;  or log ; or other ...

}

即可。

用户使用智能指针还是原来的样子:TSharePtr<A> ptrA = ......

不过注意,所有对这个智能指针的使用必须在顺序上后于

template<> struct InvalidClassTraits<A>{ typedef A_NULL NULL_CLASS } ;

这句声明,否则会导致无法链接的错误。

 

就写到这里了。欢迎大家拍砖扔手雷丢炸弹。理不辨不明,呵呵。

另外,原创文章,允许转载,转载请注明作者和出处:

李巍(noslopforever·天堂里的死神)

http://blog.csdn.net/noslopforever

发表于 @ 2007年06月05日 09:07:00|评论(loading...)|编辑

新一篇: 英雄连1V1战胜专家电脑! | 旧一篇: 实现纹理Blend编辑功能,发图。

评论

#NCB 发表于2007-06-05 09:16:26  IP: 218.247.200.*
c++是魔鬼。。。。。。。。。。。
发表评论  


登录
Csdn Blog version 3.1a
Copyright © noslopforever(天堂里的死神)