社区应用 最新帖子 精华区 社区服务 会员列表 统计排行 社区论坛任务 迷你宠物
  • 6577阅读
  • 3回复

[C/C++]一个简易的类型判别器

发帖
7
铜板
13
人品值
61
贡献值
2
交易币
0
好评度
7
信誉值
0
金币
0
所在楼道
                                一个简易的类型判别器 O>y'Nqz  
             $& ~;@*[  
                        在某些时候,我们需要判别一个对象的类型,C++提供了RTTI(运行时类型信息)机制,比如使用 typeid 关键字,但 Bjarne 建议尽量不要使用RTTI来判定对象类别,他提倡多使用使用 dynamic_cast 替代 typeid。当然typyid能准确判定对象的类型,而dynamic_cast不一定总能告诉我们对象的确切类型。 . 9G<y 4  
XE3aXK'R  
下面是一个简单的类型判别器(不能用于基本类型,如int、double等): {QaNAR=)  
代码: 全选/* P,pnga3Wu  
* File: TypeUtils.h H!IshZfktn  
* Author: kwarph [ kwarph@gmail.com ] 2C^B_FUg|]  
* Time: 2009-3-21 下午03:25:02 LE^G&<!  
* [s1pM1x  
* Copyright (C) 2008-2009, kwarph, All Rights Reserved. 0'Z\O   
*/ SkNre$>t{  
j=+"Qz/hr_  
#ifndef TYPEUTILS_H_ 5~ 'Ie<Y_  
#define TYPEUTILS_H_ *ZSdl 0e  
A~ (l{g  
template<typename T> 2(!fg4#+  
struct InstanceOf { KU9Z"9#  
Rf %HIAVE  
    template<typename T1> hjx)D  
    static bool test(const T1*& ptr) { NtGn88='{  
        const T* t = dynamic_cast<const T*> (ptr); cS .i  
        return t != 0; w)] H ^6  
    } 4 {GU6v)f  
4\5uY  
    template<typename T1> QrG`&QN  
    static bool test(T1*& ptr) { gIEl.  
        T* t = dynamic_cast<T*> (ptr); U!5)5c}G  
        return t != 0; neF]=uCWnT  
    } bF}V4"d,B3  
`<"m%>  
    template<typename T1> 9Mm!%Hu  
    static const T* get(const T1*& ptr) { yR~-k?7b  
        const T* t = dynamic_cast<const T*> (ptr); i7[uLdQ  
        return t; `BFIC7a  
    } ~:Uw g+]j  
X26   
    template<typename T1> %bXtKhg5eJ  
    static T*& get(T1*& ptr) { K!AAGj`  
        return dynamic_cast<T*> (ptr); /(C~~XP)  
    } -ZOBAG*  
}; 1Y xgR}7  
H&}ipaDO  
#endif /* TYPEUTILS_H_ */             ^t "iX9  
ra '  
Q  Q: 570508473 ,hxkk`  
邮  件:athzhang@gmail.com \[2lvft!  
电  话:(0512) 55253348,(0) 18912671348 $gle8Z-  
地  址:江苏省 昆山市 前进西路1088号虹桥大厦 2单元 6楼 n_D8JF  
评价一下你浏览此帖子的感受

精彩

感动

搞笑

开心

愤怒

无聊

灌水
发帖
7
铜板
13
人品值
61
贡献值
2
交易币
0
好评度
7
信誉值
0
金币
0
所在楼道
只看该作者 1 发表于: 2009-08-04
Re: 一个简易的类型判别器 f2)XP$:  
%!Q`e79g8  
N@o?b  
下面作一个简单的测试,假设有一组对象,其继承关系如下: \g)Xt?w0Wo  
RH;:9_*F  
animal.png g\oSG)  
    animal.png (8.28 KiB) 被浏览 187 次 9<CG s3\  
"v*8_El  
L}{`h  
]Al;l*yw  
我们可以这么使用 InstanceOf类: k5d\ w@G"~  
&.i^dO^}  
代码: 全选 ;+"f  
    Animal* a1 = new Lion; LS>G4 ]  
    Animal* a2 = new Swallow; =8 G&3 R  
pj|pcv^  
    // 1,判断 a1 是不是鸟类: Q'B6^%:<~  
    bool isBird = InstanceOf<Bird*>::test(a1); // isBird为false,a1是狮子 ?@6b>='!  
5 +9 Ze9  
    // 2,判断 a1 是不是狮子: :bU(S<%M  
    bool isLion = InstanceOf<Lion*>::test(a1); Ac k}QzXO  
f5RE9%.#~  
    // 3,判断 a2 是不是鸟类: u?+bW-D'd  
    isBird = InstanceOf<Bird*>::test(a1); // isBird为true,a2 是燕子,所以是鸟类 F r?z"  
e59dVFug.U  
P3tx|:gV  
7iC *Pr  
在 3,判断 a2 是不是鸟类 的判断中,typeid无法达到我们所要的效果,因为: TTNk r`  
8 }'|]JK  
代码: 全选 E|"=. T  
    isBird = (typeid(*a2) == typeid(Bird)); // isBird 为 false =H7xD"'%R  
i?;r7>  
g8;D/  
mo]KCi  
typeid()返回的是对象实际的类型,也就是说Swallow虽然是Bird,但这是两个不同的类型。 `RQ#.   
OV CR0  
Q  Q: 570508473  FeJr\|FT  
邮  件:]athzhang@gmail.com tYW>t9  
电  话:(0512) 55253348,(0) 18912671348 d~tuk4F  
地  址:江苏省 昆山市 前进西路1088号虹桥大厦 2单元 6楼 )
发帖
7
铜板
13
人品值
61
贡献值
2
交易币
0
好评度
7
信誉值
0
金币
0
所在楼道
只看该作者 2 发表于: 2009-08-04
Re: 一个简易的类型判别器 6V9doP]i  
K2_Qu't0$  
mumXUX  
其实很多场合用得上的,比如我们目前进行的CAD项目,在前台的界面的绘图区中选取一批对象,其中也许有Line、Conic、BezierCurve、 BSplineCurve等,但都属于Curve,我们可以对它们的共有特性进行统一修改(比如在对话框1中列举公共的特性,即Curve的属性),但如果我们选择的是一条直线,那么我们必须确定这个被选择的对象就是Line,弹出合适的对话框(罗列Line对象的可修改的属性),这个时候,我们可以用上面的InstanceOf。 ]pA(K?Lbg  
: DG)g3#  
当然,好的设计总能减少对类型确认的需要,但我想应该不能完全避免吧。 *2 "6fX[  
rk2xKm^w  
昆山轩辕高端IT培训中心 }|)R   
Q  Q: 570508473 2 mjV~  
邮  件:athzhang@gmail.com AS!6XT  
电  话:(0512) 55253348,(0) 18912671348 5,"l0nrk  
地  址:江苏省 昆山市 前进西路1088号虹桥大厦 2单元 6楼
发帖
7
铜板
13
人品值
61
贡献值
2
交易币
0
好评度
7
信誉值
0
金币
0
所在楼道
只看该作者 3 发表于: 2009-08-05
Q  Q: 570508473 Y+%sBqo @  
主页:http://www.xuanyuan-soft.cn w-B^ [<  
论坛:http://www.xuanyuan-soft.cn/forums
描述
快速回复

您目前还是游客,请 登录注册
如果您在写长篇帖子又不马上发表,建议存为草稿
认证码:
验证问题:
10+5=?,请输入中文答案:十五