??xml version="1.0" encoding="utf-8" standalone="yes"?>久久热这里只有精品在线观看,69SEX久久精品国产麻豆,久久国内免费视频 http://m.shnenglu.com/Ipedo/zh-cn Sat, 28 Jun 2025 01:41:42 GMT Sat, 28 Jun 2025 01:41:42 GMT 60 Pass在SDK2004里被ҎBeginPass?/title> http://m.shnenglu.com/Ipedo/archive/2006/04/14/5516.htmlIpedo Ipedo Fri, 14 Apr 2006 02:28:00 GMT http://m.shnenglu.com/Ipedo/archive/2006/04/14/5516.html http://m.shnenglu.com/Ipedo/comments/5516.html http://m.shnenglu.com/Ipedo/archive/2006/04/14/5516.html#Feedback 0 http://m.shnenglu.com/Ipedo/comments/commentRss/5516.html http://m.shnenglu.com/Ipedo/services/trackbacks/5516.html for( number of passes ) { pDevice->BeginPass(); pDevice->CommitChanges(); // 在这里绘制场景?br /> //。。。。?br /> pDevice->EndPass(); } ]]> 农历--|页昄 http://m.shnenglu.com/Ipedo/archive/2006/01/06/2463.htmlIpedo Ipedo Fri, 06 Jan 2006 04:04:00 GMT http://m.shnenglu.com/Ipedo/archive/2006/01/06/2463.html http://m.shnenglu.com/Ipedo/comments/2463.html http://m.shnenglu.com/Ipedo/archive/2006/01/06/2463.html#Feedback 1 http://m.shnenglu.com/Ipedo/comments/commentRss/2463.html http://m.shnenglu.com/Ipedo/services/trackbacks/2463.html <script language="javascript"> <!-- var bsYear; var bsDate; var bsWeek; var arrLen=8; //数组长度 var sValue=0; //当年的秒?BR>var dayiy=0; //当年W几?BR>var miy=0; //月䆾的下?BR>var iyear=0; //q䆾标记 var dayim=0; //当月W几?BR>var spd=86400; //每天的秒?/P>
var year1999="30;29;29;30;29;29;30;29;30;30;30;29"; //354 var year2000="30;30;29;29;30;29;29;30;29;30;30;29"; //354 var year2001="30;30;29;30;29;30;29;29;30;29;30;29;30"; //384 var year2002="30;30;29;30;29;30;29;29;30;29;30;29"; //354 var year2003="30;30;29;30;30;29;30;29;29;30;29;30"; //355 var year2004="29;30;29;30;30;29;30;29;30;29;30;29;30"; //384 var year2005="29;30;29;30;29;30;30;29;30;29;30;29"; //354 var year2006="30;29;30;29;30;30;29;29;30;30;29;29;30";
var month1999="正月;二月;三月;四月;五月;六月;七月;八月;九月;十月;十一?十二? var month2001="正月;二月;三月;四月;闰四?五月;六月;七月;八月;九月;十月;十一?十二? var month2004="正月;二月;C?三月;四月;五月;六月;七月;八月;九月;十月;十一?十二? var month2006="正月;二月;三月;四月;五月;六月;七月;C?八月;九月;十月;十一?十二? var Dn="初一;初二;初三;初四;初五;初六;初七;初八;初九;初十;十一;十二;十三;十四;十五;十六;十七;十八;十九;二十;廿一;廿二;廿三;廿四;廿五;廿六;廿七;廿八;廿九;三十";
var Ys=new Array(arrLen); Ys[0]=919094400;Ys[1]=949680000;Ys[2]=980265600; Ys[3]=1013443200;Ys[4]=1044028800;Ys[5]=1074700800; Ys[6]=1107878400;Ys[7]=1138464000;
var Yn=new Array(arrLen); //农历q的名称 Yn[0]="己卯q?;Yn[1]="庚辰q?;Yn[2]="辛埩q?; Yn[3]="午q?;Yn[4]="癸未q?;Yn[5]="甲申q?; Yn[6]="乙酉q?;Yn[7]="丙戌q?; var D=new Date(); var yy=D.getYear(); var mm=D.getMonth()+1; var dd=D.getDate(); var ww=D.getDay(); if (ww==0) ww="<font color=RED>星期?; if (ww==1) ww="星期一"; if (ww==2) ww="星期?; if (ww==3) ww="星期?; if (ww==4) ww="星期?; if (ww==5) ww="星期?; if (ww==6) ww="<font color=RED>星期?; ww=ww; var ss=parseInt(D.getTime() / 1000); if (yy<100) yy="19"+yy;
for (i=0;i<arrLen;i++) if (ss>=Ys[i]){ iyear=i; sValue=ss-Ys[i]; //当年的秒?BR> } dayiy=parseInt(sValue/spd)+1; //当年的天?/P>
var dpm=year1999; if (iyear==1) dpm=year2000; if (iyear==2) dpm=year2001; if (iyear==3) dpm=year2002; if (iyear==4) dpm=year2003; if (iyear==5) dpm=year2004; if (iyear==6) dpm=year2005; if (iyear==7) dpm=year2006; dpm=dpm.split(";");
var Mn=month1999; if (iyear==2) Mn=month2001; if (iyear==5) Mn=month2004; if (iyear==7) Mn=month2006; Mn=Mn.split(";");
var Dn="初一;初二;初三;初四;初五;初六;初七;初八;初九;初十;十一;十二;十三;十四;十五;十六;十七;十八;十九;二十;廿一;廿二;廿三;廿四;廿五;廿六;廿七;廿八;廿九;三十"; Dn=Dn.split(";");
dayim=dayiy;
var total=new Array(13); total[0]=parseInt(dpm[0]); for (i=1;i<dpm.length-1;i++) total[i]=parseInt(dpm[i])+total[i-1]; for (i=dpm.length-1;i>0;i--) if (dayim>total[i-1]){ dayim=dayim-total[i-1]; miy=i; } bsWeek=ww; bsDate=yy+"q?+mm+"?; bsDate2=dd; bsYear="农历"+Yn[iyear]; bsYear2=Mn[miy]+Dn[dayim-1]; if (ss>=Ys[7]||ss<Ys[0]) bsYear=Yn[7]; /* 修改下面的表格属?/ function CAL(){ document.write("<table border='1' cellspacing='3' width='120' bordercolor='#009B00' bgcolor='#FFFFFF' height='110' cellpadding='2'"); document.write("<tr><td align='center'><b><font color=#008040>"+bsDate+"</font><br><font face='Arial' size='6' color=#FF8040>"+bsDate2+"</font><br><font color=#008040><span style='FONT-SIZE: 10.5pt'>"); document.write(bsWeek+"</span><br>"+"<br></b><font color=#9B4E00>"); document.write(bsYear+"<br>"+bsYear2+"</td></tr></table>"); } //--> </script><script language="javascript">CAL();</script>
]]>关于C++中RTTI的编码实?/title> http://m.shnenglu.com/Ipedo/archive/2005/12/12/1699.htmlIpedo Ipedo Mon, 12 Dec 2005 11:39:00 GMT http://m.shnenglu.com/Ipedo/archive/2005/12/12/1699.html http://m.shnenglu.com/Ipedo/comments/1699.html http://m.shnenglu.com/Ipedo/archive/2005/12/12/1699.html#Feedback 0 http://m.shnenglu.com/Ipedo/comments/commentRss/1699.html http://m.shnenglu.com/Ipedo/services/trackbacks/1699.html 摘要Q?/font> RTTI
(Run-Time Type
Identification)是面向对象程序设计中一U重要的技术。现行的C++标准对RTTI已经有了明确的支持。不q在某些情况下出于特D的开发需
要,我们需要自q码来实现。本文介l了一些关于RTTI的基知识及其原理和实现。 RTTI需求:
和很多其他语a一PC++是一U静态类型语a。其数据cd是在~译期就定的,不能在运行时更改。然而由于面向对象程序设计中多态性的要求QC++?
的指针或引用(Reference)本n的类型,可能与它实际代表(指向或引?的类型ƈ不一致。有时我们需要将一个多态指针{换ؓ其实际指向对象的c?
型,需要知道运行时的类型信息,q就产生了运行时cd识别的要求?br> C++对RTTI的支?/font>Q?/b> C++提供了两个关键字typeid和dynamic_cast和一个type_infocL支持RTTIQ?br> dynamic_cast操作W: 它允许在q行时刻q行cd转换Q从而ɽE序能够在一个类层次l构安全地{换类型。dynamic_cast提供了两U{换方式,把基cL针{换成zcL针,或者把指向基类的左D{换成zcȝ引用。见下例讲述Q?br>
void company::payroll(employee *pe) { //Ҏ针{换失败,dynamic_castq回NULL if(programmer *pm=dynamic_cast(pe)){ pm->bonus(); } } void company::payroll(employee &re) { try{ //对引用{换失败的话,则会以抛出异常来报告错误 programmer &rm=dynamic_cast(re); pm->bonus(); } catch(std::bad_cast){ } }
q里bonus是programmer的成员函敎ͼ基类employee不具备这个特性。所以我们必M用安全的由基cdzcȝ型{换,识别出programmer指针?br> typeid操作W: 它指出指针或引用指向的对象的实际zcd?br> 例如Q?br>
employee* pe=new manager; typeid(*pe)==typeid(manager) //true
typeid可以用于作用于各U类型名Q对象和内置基本数据cd的实例、指针或者引用,当作用于指针和引用将q回它实际指向对象的cd信息。typeid的返回是type_infocd?br> type_infoc:q个cȝ切定义是与~译器实现相关的Q下面是《C++ Primer》中l出的定?参考资料[2]中谈到编译器必须提供的最信息量)Q?br>
class type_info { private: type_info(const type_info&); type_info& operator=( const type_info& ); public: virtual ~type_info(); int operator==( const type_info& ) const; int operator!=( const type_info& ) const; const char* name() const; };实现目标Q?/font> 实现的方?/b> Ҏ一Q利用多态来取得指针或应用的实际cd信息 q是一个最单的ҎQ也是作者目前所采用的办法?br> 实现Q?br>
enum ClassType{ UObjectClass, URectViewClass, UDialogClass, …?br>}; class UObject{ virtual char* GetClassName() const { return "UObject"; }; virtual ClassType TypeOfClass(){ return UObjectClass; }; }; class UDialog{ virtual char* GetClassName() const { return "UDialog"; }; virtual ClassType TypeOfClass(){ return UDialogClass; }; };
CZQ?br>
UObject po=new UObject; UObject pr=new URectView; UObject pd=new UDialog; cout << "po is a " << po->GetClassName() << endl; cout << "pr is a " << pr->GetClassName() << endl; cout << "pd is a " << pd->GetClassName() << endl; cout<TypeOfClass()==UObjectClass< cout<TypeOfClass()==URectViewClass< cout<TypeOfClass()==UDialogClass< cout<TypeOfClass()==UObjectClass< cout<TypeOfClass()==UDialogClass<< td>
输出Q?br>
po is a UObjectClass pr is a URectViewClass pd is a UDialogClass true true true false false
q种实现Ҏ也就是在基类中提供一个多态的ҎQ这个方法返回一个类型信息。这h们能够知道一个指针所指向对象的具体类型,可以满一些简单的要求?br> 但是很显Ӟq样的方法只实现了typeid的部分功能,q存在很多缺点: 1?用户每增加一个类必须覆盖GetClassName和TypeOfClass两个ҎQ如果忘了,会导致程序错误?br> 2?q里的类名和cL识信息不以实现dynamic_cast的功能,从这个意义上而言此方案根本不能称为RTTI?br> 3?用户必须手工l护每个cȝcd与标识,q限制了以库的方式提供给用户的可能?br> 4?用户必须手工dGetClassName和TypeOfClass两个ҎQ用ƈ不方ѝ?br> 其中上面的部分问题我们可以采用C/C++中的宏技?Macro Magic)来解冻Iq个可以在我们的最l解x案的代码中看到。下面采用方案二中将予以解决上述问题?br> Ҏ二:以一个类型表来存储类型信?/b> q种Ҏ考虑使用一个类l构Q除了保留原有的整型cIDQ类名字W串外,增加了一个指向基cTypeInfo成员的指针?br>
struct TypeInfo { char* className; int type_id; TypeInfo* pBaseClass; operator== (const TypeInfo& info){ return this==&info; } operator!= (const TypeInfo& info){ return this!=&info; } };
从这里可以看刎ͼ以这U方式实现的RTTI不支持多重ѝ所q多重承在E序设计中ƈ非必,而且也不推荐。下面的代码中,我将为DP9900软g?
目组中类层次l构中的几个cL加RTTI功能。DP9900目中,l大部分的类都以单承方式从UObjectq个根类直接或间接承而来。这h们就
可以从UObject开始,加入我们RTTI支持所需要的数据和方法?br>
class UObject { public: bool IsKindOf(TypeInfo& cls); //判别某个对象是否属于某一个类 public: virtual int GetTypeID(){return rttiTypeInfo.type_id;} virtual char* GetTypeName(){return rttiTypeInfo.className;} virtual TypeInfo& GetTypeInfo(){return rttiTypeInfo;} static TypeInfo& GetTypeInfoClass(){return rttiTypeInfo;} private: static TypeInfo rttiTypeInfo; }; //依次为className、type_id、pBaseClass赋?br>TypeInfo UObject::rttiTypeInfo={"UObject",0,NULL};
考虑从UObject这个TypeInfocM为每一个新增类的静态成员,q样一个类的所有对象将׃nTypeInfo的唯一实例。我们希望能够在E?
序运行之前就为type_id,className做好初始化,q让pBaseClass指向基类的这个TypeInfo?br> 每个cȝTypeInfo成员U定使用rttiTypeInfo的命名,Z避免命名冲突Q我们将其作为private成员。有了基cȝ支持q不够,当用户需要RTTI支持Q还需要自己来做一些事情: 1?zc需要从UObjectl承?br> 2?drttiTypeInfo变量?br> 3?在类外正初始化rttiTypeInfo静态成员?br> 4?覆盖GetTypeID、GetTypeName、GetTypeInfo、GetTypeInfoClass四个成员函数?br> 如下所C:
class UView:public UObject { public: virtual int GetTypeID(){return rttiTypeInfo.type_id;} virtual char* GetTypeName(){return rttiTypeInfo.className;} virtual TypeInfo& GetTypeInfo(){return rttiTypeInfo;} static TypeInfo& GetTypeInfoClass(){return rttiTypeInfo;} private: static TypeInfo rttiTypeInfo; };
有了前三步,q样我们可以得C个不太复杂的链表――这是一늱型信息构成的"?Q与数据l构中的树的唯一差别是其指针方向相反?br> q样Q从M一个UObject的子c,着pBaseClass往上找Q总能遍历它的所有父c,最l到达UObject?br> 在这个链表的基础上,要判别某个对象是否属于某一个类很单。下面给出UObject::IsKindOf()的实现?br>
bool UObject::IsKindOf(TypeInfo& cls) { TypeInfo* p=&(this->GetTypeInfo()); while(p!=NULL){ if(p->type_id==cls.type_id) return true; p=p->pBaseClass; } return false; }
有了IsKindOf的支持,dynamic_cast的功能也可以用一个简单的safe_cast来实玎ͼ
template inline T* safe_cast(UObject* ptr,TypeInfo& cls) { return (ptr->IsKindOf(cls)?(T*)ptr:NULL); }
xQ我们已l能够从功能上完成前面的目标了,不过用户要用这个类库的RTTI功能q很ȝQ要敲入一大堆对他们毫无意义的函数代码Q要在初始化
rttiTypeInfo静态成员时手工讄cID与类名。其实这些麻烦完全不必交l我们的用户Q适当采用一些宏技?Macro
Magic)Q就可以让C++的预处理器来替我们写很多枯燥的代码。关于宏不是本文的重点,你可以从最l代码清单看到它们。下面再谈谈关于cID的问题?br> cID Z使不同类型的对象可区分,用一个给每个TypeInfo对象一个类ID来作为比较的依据是必要的?br>?
实对于我们这里的需求和实现Ҏ而言Q其实类IDq不是必ȝ。每一个支持RTTI的类都包含了一个静态TypeInfo对象Q这个对象的地址是在进E?
中全局唯一。但考虑到其他一些技术如Q动态对象创建、对象序列化{,它们可能会要求RTTIl出一个静态不变的ID。在本文的实CQ对此作了有益的?
试?br> 首先声明一个用来生递增cID的全局变量。再声明如下一个结构,没有数据成员Q只有一个构造函数用于初始化TypeInfo的类IDQ?br>
extern int TypeInfoOrder=0; struct InitTypeInfo { InitTypeInfo(TypeInfo* info) { info->type_id=TypeInfoOrder++; } };
为UObjectd一个private的静态成员及其初始化Q?br>
class UObject { //…?br>private: static InitTypeInfo initClassInfo; }; InitTypeInfo UObject::initClassInfo(&(UObject::rttiTypeInfo));
q且Ҏ一个从UObjectz的子cMq行同样的添加。这h看刎ͼ在C++d数执行前Q启动代码将替我们调用每一个类?
initClassInfo成员的构造函数InitTypeInfo::InitTypeInfo(TypeInfo*
info)Q而正是这个函数替我们产生q设|了cID。InitTypeInfo的构造函数还可以替我们做其他一些有用的初始化工作,比如所有的
TypeInfo信息dC个表格里Q让我们可以很方便的遍历它?br> 但实践与查阅资料让我们发玎ͼ׃C++中对静态成员初始化的顺序没有明的规定Q所以这L方式产生出来的类IDq完全静态,换一个编译器~译执行产生的结果可能完全不同?br> q有一个可以考虑的方案是采用某种无冲HHASH法Q将cd转换成ؓ一个唯一整数。用标准CRC32法从类型名计算Z个整C为类ID也许是个不错的想法[3]?br> E序清单
// URtti.h #ifndef __URTTI_H__ #define __URTTI_H__ class UObject; struct TypeInfo { char* className; int type_id; TypeInfo* pBaseClass; operator== (const TypeInfo& info){ return this==&info; } operator!= (const TypeInfo& info){ return this!=&info; } }; inline std::ostream& operator<< (std::ostream& os,TypeInfo& info) { return (os<< "[" << &info << "]" << "\t" << info.type_id << ":" << info.className << ":" << info.pBaseClass << std::endl); } extern int TypeInfoOrder; struct InitTypeInfo { InitTypeInfo(/*TypeInfo* base,*/TypeInfo* info) { info->type_id=TypeInfoOrder++; } }; #define TYPEINFO_OF_CLASS(class_name) (class_name::GetTypeInfoClass()) #define TYPEINFO_OF_OBJ(obj_name) (obj_name.GetTypeInfo()) #define TYPEINFO_OF_PTR(ptr_name) (ptr_name->GetTypeInfo()) #define DECLARE_TYPEINFO(class_name) \ public: \ virtual int GetTypeID(){return TYPEINFO_MEMBER(class_name).type_id;} \ virtual char* GetTypeName(){return TYPEINFO_MEMBER(class_name).className;} \ virtual TypeInfo& GetTypeInfo(){return TYPEINFO_MEMBER(class_name);} \ static TypeInfo& GetTypeInfoClass(){return TYPEINFO_MEMBER(class_name);} \ private: \ static TypeInfo TYPEINFO_MEMBER(class_name); \ static InitTypeInfo initClassInfo; \ #define IMPLEMENT_TYPEINFO(class_name,base_name) \ TypeInfo class_name::TYPEINFO_MEMBER(class_name)= \ {#class_name,0,&(base_name::GetTypeInfoClass())}; \ InitTypeInfo class_name::initClassInfo(&(class_name::TYPEINFO_MEMBER(class_name))); #define DYNAMIC_CAST(object_ptr,class_name) \ safe_cast(object_ptr,TYPEINFO_OF_CLASS(class_name)) #define TYPEINFO_MEMBER(class_name) rttiTypeInfo class UObject { public: bool IsKindOf(TypeInfo& cls); public: virtual int GetTypeID(){return TYPEINFO_MEMBER(UObject).type_id;} virtual char* GetTypeName(){return TYPEINFO_MEMBER(UObject).className;} virtual TypeInfo& GetTypeInfo(){return TYPEINFO_MEMBER(UObject);} static TypeInfo& GetTypeInfoClass(){return TYPEINFO_MEMBER(UObject);} private: static TypeInfo TYPEINFO_MEMBER(UObject); static InitTypeInfo initClassInfo; }; template inline T* safe_cast(UObject* ptr,TypeInfo& cls) { return (ptr->IsKindOf(cls)?(T*)ptr:NULL); } #endif // URtti.cpp #include "urtti.h" extern int TypeInfoOrder=0; TypeInfo UObject::TYPEINFO_MEMBER(UObject)={"UObject",0,NULL}; InitTypeInfo UObject::initClassInfo(&(UObject::TYPEINFO_MEMBER(UObject))); bool UObject::IsKindOf(TypeInfo& cls) { TypeInfo* p=&(this->GetTypeInfo()); while(p!=NULL){ if(p->type_id==cls.type_id) return true; p=p->pBaseClass; } return false; } // mail.cpp #include #include "urtti.h" using namespace std; class UView:public UObject { DECLARE_TYPEINFO(UView) }; IMPLEMENT_TYPEINFO(UView,UObject) class UGraph:public UObject { DECLARE_TYPEINFO(UGraph) }; IMPLEMENT_TYPEINFO(UGraph,UObject) void main() { UObject* po=new UObject; UView* pv=new UView; UObject* pg=new UGraph; if(DYNAMIC_CAST(po,UView)) cout << "po => UView succeed" << std::endl; else cout << "po => UView failed" << std::endl; if(DYNAMIC_CAST(pv,UView)) cout << "pv => UView succeed" << std::endl; else cout << "pv => UView failed" << std::endl; if(DYNAMIC_CAST(po,UGraph)) cout << "po => UGraph succeed" << std::endl; else cout << "po => UGraph failed" << std::endl; if(DYNAMIC_CAST(pg,UGraph)) cout << "pg => UGraph succeed" << std::endl; else cout << "pg => UGraph failed" << std::endl; }
实现l果 本文实现了如下几个宏来支持RTTIQ它们的使用Ҏ都可以在上面的代码中扑ֈQ?br>
宏函?/td>
功能及参数说?/td>
DECLARE_TYPEINFO(class_name)
为类dRTTI功能攑֜cd明的起始位置
IMPLEMENT_TYPEINFO(class_name,base)
同上Q放在类定义M位置
TYPEINFO_OF_CLASS(class_name)
相当于typeid(cd)
TYPEINFO_OF_OBJ(obj_name)
相当于typeid(对象)
TYPEINFO_OF_PTR(ptr_name)
相当于typeid(指针)
DYNAMIC_CAST(object_ptr,class_name)
相当于dynamic_castobject_ptr
性能试 试代码Q?/b> q里使用相同ơ数的DYNAMIC_CAST和dynamic_castq行Ҏ试Q在VC6.0下编译运行,使用默认的Release~译配置选项。ؓ了避免编译器优化D的不公^试l果Q我在@环中加入了无意义的计数操作?br>
void main() { UObject* po=new UObject; UView* pv=new UView; UObject* pg=new UGraph; int a,b,c,d; a=b=c=d=0; const int times=30000000; cerr << "旉试输出Q? << endl; cerr << "start my DYNAMIC_CAST at: " << time(NULL) << endl; for(int i=0;i if(DYNAMIC_CAST(po,UView)) a++; else a--; if(DYNAMIC_CAST(pv,UView)) b++; else b--; if(DYNAMIC_CAST(po,UGraph)) c++; else c--; if(DYNAMIC_CAST(pg,UGraph)) d++; else d--; } cerr << "end my DYNAMIC_CAST at: " << time(NULL) << endl; cerr << "start c++ dynamic_cast at: " << time(NULL) << endl; for(i=0;i if(dynamic_cast(po)) a++; else a--; if(dynamic_cast(pv)) b++; else b--; if(dynamic_cast(po)) c++; else c--; if(dynamic_cast(pg)) d++; else d--; } cerr << "end c++ dynamic_cast at: " << time(NULL) << endl; cerr << a << b << c << d << endl; }
q行l果Q?br>
start my DYNAMIC_CAST at: 1021512140 end my DYNAMIC_CAST at: 1021512145 start c++ dynamic_cast at: 1021512145 end c++ dynamic_cast at: 1021512160
q是上述条g下的试输出Q我们可以看刎ͼ本文实现的这个精RTTIҎq行DYNAMIC_CAST的时间开销只有dynamic_cast?/3。ؓ了得到更全面的数据,q进行了DEBUG~译配置选项下的试?br> 输出Q?br>
start my DYNAMIC_CAST at: 1021512041 end my DYNAMIC_CAST at: 1021512044 start c++ dynamic_cast at: 1021512044 end c++ dynamic_cast at: 1021512059
q种情况下DYNAMIC_CASTq行速度要比dynamic_cast慢一倍左叟뀂如果在Release~译配置选项下将UObject::
IsKindOfҎҎ如下inline函数Q我们将得到更让人兴奋的l果QDYNAMIC_CASTq行旉只有dynamic_cast?
1/5Q?br>
inline bool UObject::IsKindOf(TypeInfo& cls) { for(TypeInfo* p=&(this->GetTypeInfo());p!=NULL;p=p->pBaseClass) if(p==&cls) return true; return false; }
输出Q?br>
start my DYNAMIC_CAST at: 1021512041 end my DYNAMIC_CAST at: 1021512044 start c++ dynamic_cast at: 1021512044 end c++ dynamic_cast at: 1021512059
l论Q?/b>
由本文的实践可以得出l论Q自己动手编码实现RTTI是简单可行的。这L实现可以在编译器优秀的代码优化中表现出比dynamic_cast更好的?
能,而且没有带来q多的存储开销。本文的RTTI以性能Z要设计目标,在实C一定程度上受到了MFC的媄响。适于嵌入式环境?/span>
]]> cQ+随笔1 http://m.shnenglu.com/Ipedo/archive/2005/12/06/1567.htmlIpedo Ipedo Tue, 06 Dec 2005 09:01:00 GMT http://m.shnenglu.com/Ipedo/archive/2005/12/06/1567.html http://m.shnenglu.com/Ipedo/comments/1567.html http://m.shnenglu.com/Ipedo/archive/2005/12/06/1567.html#Feedback 0 http://m.shnenglu.com/Ipedo/comments/commentRss/1567.html http://m.shnenglu.com/Ipedo/services/trackbacks/1567.html 2、当函数参数是大的结构的时候,量使用l构的指针或引用Q避免大的内存操作(复制的开销Q,参数使用的时候注意不希望函数内改变原来值时Q应该加上const修饰W号Q?BR>3、用多重承时应该避免出现DODQ钻矛_l承树)Q虚l承可以解决q个问题Q但是应用时应该量避免q二者; 4、尽量多的用constQ?BR>5、引用只能被初始化一ơ,指针可以被多ơ赋|可以q么_引用是const指针Q引用必dx的时候初始化Q指针则不用Q引用不能ؓNULLQ也不能new和deleteQ它更象一个对象; 6、四UcQ+风格的强制{换,static_cast(规定被{换的二者存在联p,在同一l承体系?Qconst_castQ将帔R转换为非帔RQ,reinterpret_castQ{换Q何类型,同c的强制{换)Qdynamic_castQ动态类型{换,需要编译器支持q行期类型信息RTTIQ?img src ="http://m.shnenglu.com/Ipedo/aggbug/1567.html" width = "1" height = "1" /> ]]> 实用宏-QvcQ+中方便注?/title> http://m.shnenglu.com/Ipedo/archive/2005/12/02/1495.htmlIpedo Ipedo Fri, 02 Dec 2005 06:46:00 GMT http://m.shnenglu.com/Ipedo/archive/2005/12/02/1495.html http://m.shnenglu.com/Ipedo/comments/1495.html http://m.shnenglu.com/Ipedo/archive/2005/12/02/1495.html#Feedback 0 http://m.shnenglu.com/Ipedo/comments/commentRss/1495.html http://m.shnenglu.com/Ipedo/services/trackbacks/1495.html 'd文g头定?BR> Public Sub AddFileHead()
Dim objTextSelection As TextSelection Dim comment As String objTextSelection = CType(DTE.ActiveDocument.Selection, EnvDTE.TextSelection) 'objTextSelection.LineUp() objTextSelection.NewLine() objTextSelection.Text = comment + "http://===================================================================" objTextSelection.NewLine() objTextSelection.Text = comment + "/** \file" objTextSelection.NewLine() objTextSelection.Text = comment + "* Filename: " + DTE.ActiveDocument.Name objTextSelection.NewLine() objTextSelection.Text = comment + "*" objTextSelection.NewLine() objTextSelection.Text = comment + "* Desc:" objTextSelection.NewLine() objTextSelection.Text = comment + "*" objTextSelection.NewLine() objTextSelection.Text = comment + "* His: Ipedo create @ " + Date.Now objTextSelection.NewLine() objTextSelection.Text = comment + "*/" objTextSelection.NewLine() objTextSelection.Text = comment + "http://==================================================================="
End Sub 'd文g函数定义 Public Sub AddFunctionHead()
Dim objTextSelection As TextSelection Dim comment As String objTextSelection = CType(DTE.ActiveDocument.Selection, EnvDTE.TextSelection) 'objTextSelection.LineUp() objTextSelection.NewLine() objTextSelection.Text = comment + "/** \brief" objTextSelection.NewLine() objTextSelection.Text = comment + " " + "* 函数功能Q? objTextSelection.NewLine() objTextSelection.Text = comment + "*" objTextSelection.NewLine() objTextSelection.Text = comment + "* 函数说明Q? objTextSelection.NewLine() objTextSelection.Text = comment + "*" objTextSelection.NewLine() objTextSelection.Text = comment + "* \param _f1 W一个Q点参?" objTextSelection.NewLine() objTextSelection.Text = comment + "* \param _f2 W二个Q点参?" objTextSelection.NewLine() objTextSelection.Text = comment + "* \return bool q回两个点数是否相{?q回true时表C相{?" objTextSelection.NewLine() objTextSelection.Text = comment + "*" objTextSelection.NewLine() objTextSelection.Text = comment + "* 法描述Q? objTextSelection.NewLine() objTextSelection.Text = comment + "* Q描q内容)" objTextSelection.NewLine() objTextSelection.Text = comment + "*/"
End Sub Sub 文g注释() DTE.ActiveDocument.Selection.Text = "http://===================================================================" DTE.ActiveDocument.Selection.NewLine() DTE.ActiveDocument.Selection.Text = "/** \file " DTE.ActiveDocument.Selection.NewLine() 'DTE.ActiveDocument.Selection.Indent() DTE.ActiveDocument.Selection.Text = "* Filename : " + DTE.ActiveDocument.Name DTE.ActiveDocument.Selection.NewLine() DTE.ActiveDocument.Selection.Text = "* Desc : " DTE.ActiveDocument.Selection.NewLine() DTE.ActiveDocument.Selection.Text = "* His : Windy create @" + Date.Now DTE.ActiveDocument.Selection.NewLine() DTE.ActiveDocument.Selection.NewLine() DTE.ActiveDocument.Selection.DeleteLeft() DTE.ActiveDocument.Selection.Text = "*/" DTE.ActiveDocument.Selection.NewLine() DTE.ActiveDocument.Selection.Text = "http://===================================================================" DTE.ActiveDocument.Selection.StartOfLine(vsStartOfLineOptions.vsStartOfLineOptionsFirstText) End Sub
]]>BMP文gl构 http://m.shnenglu.com/Ipedo/archive/2005/11/12/1104.htmlIpedo Ipedo Sat, 12 Nov 2005 09:34:00 GMT http://m.shnenglu.com/Ipedo/archive/2005/11/12/1104.html http://m.shnenglu.com/Ipedo/comments/1104.html http://m.shnenglu.com/Ipedo/archive/2005/11/12/1104.html#Feedback 2 http://m.shnenglu.com/Ipedo/comments/commentRss/1104.html http://m.shnenglu.com/Ipedo/services/trackbacks/1104.html ---- 1. BMP文gl成
---- BMP文g由文件头、位图信息头、颜色信息和囑Ş数据四部分组成?
---- 2. BMP文g?
---- BMP文g头数据结构含有BMP文g的类型、文件大和位图起始位置{信息?
---- 其结构定义如?
typedef struct tagBITMAPFILEHEADER
{
WORDbfType; // 位图文g的类型,必须为BM
DWORD bfSize; // 位图文g的大,以字节ؓ单位
WORDbfReserved1; // 位图文g保留字,必须?
WORDbfReserved2; // 位图文g保留字,必须?
DWORD bfOffBits; // 位图数据的v始位|,以相对于位图
// 文g头的偏移量表C,以字节ؓ单位
} BITMAPFILEHEADER;
---- 3. 位图信息?
BMP位图信息头数据用于说明位囄寸{信息?
typedef struct tagBITMAPINFOHEADER{
DWORD biSize; // 本结构所占用字节?
LONGbiWidth; // 位图的宽度,以像素ؓ单位
LONGbiHeight; // 位图的高度,以像素ؓ单位
WORD biPlanes; // 目标讑֤的别,必须?
WORD biBitCount// 每个像素所需的位敎ͼ必须?(双色),
// 4(16?Q?(256??4(真彩?之一
DWORD biCompression; // 位图压羃cdQ必L 0(不压~?,
// 1(BI_RLE8压羃cd)?(BI_RLE4压羃cd)之一
DWORD biSizeImage; // 位图的大,以字节ؓ单位
LONGbiXPelsPerMeter; // 位图水^分L率,每米像素?
LONGbiYPelsPerMeter; // 位图垂直分L率,每米像素?
DWORD biClrUsed;// 位图实际使用的颜色表中的颜色?
DWORD biClrImportant;// 位图昄q程中重要的颜色?
} BITMAPINFOHEADER;
---- 4. 颜色?
---- 颜色表用于说明位图中的颜Ԍ它有若干个表,每一个表Ҏ一个RGBQUADcd的结构,定义一U颜艌ӀRGBQUADl构的定义如?
typedef struct tagRGBQUAD {
BYTErgbBlue;// 蓝色的亮?D围ؓ0-255)
BYTErgbGreen; // l色的亮?D围ؓ0-255)
BYTErgbRed; // U色的亮?D围ؓ0-255)
BYTErgbReserved;// 保留Q必Mؓ0
} RGBQUAD;
颜色表中RGBQUADl构数据的个数有biBitCount来确?
当biBitCount=1,4,8Ӟ分别?,16,256个表?
当biBitCount=24Ӟ没有颜色表项?
位图信息头和颜色表组成位图信息,BITMAPINFOl构定义如下:
typedef struct tagBITMAPINFO {
BITMAPINFOHEADER bmiHeader; // 位图信息?
RGBQUAD bmiColors[1]; // 颜色?
} BITMAPINFO;
---- 5. 位图数据
---- 位图数据记录了位囄每一个像素|记录序是在扫描行内是从左到?扫描行之间是从下C。位囄一个像素值所占的字节?
当biBitCount=1Ӟ8个像素占1个字?
当biBitCount=4Ӟ2个像素占1个字?
当biBitCount=8Ӟ1个像素占1个字?
当biBitCount=24?1个像素占3个字?
Windows规定一个扫描行所占的字节数必L 4的倍数(即以long为单?,不的以0填充Q?
一个扫描行所占的字节数计方? DataSizePerLine= (biWidth* biBitCount+31)/8;
// 一个扫描行所占的字节?DataSizePerLine= DataSizePerLine/4*4; // 字节数必L4的倍数
位图数据的大?不压~情况下): DataSize= DataSizePerLine* biHeight;
]]> 关于MFC对象 http://m.shnenglu.com/Ipedo/archive/2005/11/12/1103.htmlIpedo Ipedo Sat, 12 Nov 2005 08:57:00 GMT http://m.shnenglu.com/Ipedo/archive/2005/11/12/1103.html http://m.shnenglu.com/Ipedo/comments/1103.html http://m.shnenglu.com/Ipedo/archive/2005/11/12/1103.html#Feedback 0 http://m.shnenglu.com/Ipedo/comments/commentRss/1103.html http://m.shnenglu.com/Ipedo/services/trackbacks/1103.html 阅读全文 ]]> 内存泄露?/title> http://m.shnenglu.com/Ipedo/archive/2005/10/27/867.htmlIpedo Ipedo Thu, 27 Oct 2005 07:49:00 GMT http://m.shnenglu.com/Ipedo/archive/2005/10/27/867.html http://m.shnenglu.com/Ipedo/comments/867.html http://m.shnenglu.com/Ipedo/archive/2005/10/27/867.html#Feedback 4 http://m.shnenglu.com/Ipedo/comments/commentRss/867.html http://m.shnenglu.com/Ipedo/services/trackbacks/867.html 文g开始处加入下列定义 #define _CRTDBG_MAP_ALLOC #include <stdlib.h> #include <crtdbg.h> E序退出时加入以下函数Q?BR> _CrtDumpMemoryLeaks(); 如果有泄漏会昄 e:\myproject\mltithrd.14\mltithrd.cpp(95) : {68} client block at 0x00372550, subtype c0, 144 bytes long. a CMultiDocTemplate object at $00372550, 144 bytes long ]]> 关于list control控g http://m.shnenglu.com/Ipedo/archive/2005/10/26/861.htmlIpedo Ipedo Wed, 26 Oct 2005 06:44:00 GMT http://m.shnenglu.com/Ipedo/archive/2005/10/26/861.html http://m.shnenglu.com/Ipedo/comments/861.html http://m.shnenglu.com/Ipedo/archive/2005/10/26/861.html#Feedback 1 http://m.shnenglu.com/Ipedo/comments/commentRss/861.html http://m.shnenglu.com/Ipedo/services/trackbacks/861.html m_list1.SetExtendedStyle( LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES|LVS_EX_CHECKBOXES ); LVS_EX_FULLROWSELECT表示可以点中行中的Q意一个列选中q一条记?BR>LVS_EX_GRIDLINES表示列之间有分隔W号 LVS_EX_CHECKBOXES 表示每一行第一列是checkbox ]]> 新的开?/title> http://m.shnenglu.com/Ipedo/archive/2005/10/26/857.htmlIpedo Ipedo Wed, 26 Oct 2005 01:47:00 GMT http://m.shnenglu.com/Ipedo/archive/2005/10/26/857.html http://m.shnenglu.com/Ipedo/comments/857.html http://m.shnenglu.com/Ipedo/archive/2005/10/26/857.html#Feedback 1 http://m.shnenglu.com/Ipedo/comments/commentRss/857.html http://m.shnenglu.com/Ipedo/services/trackbacks/857.html 阅读全文 ]]>
ٸƷþ |
ھƷþ鶹Ħ |
þAV뾫Ʒ |
þ99þ99Ʒӿ |
ɫþþþþþС˵ |
þþþþҹƷƷ |
Ʒþþ |
ɫۺϺϾþۺӿ |
ɫۺϾþ |
þþƷƵ91 |
þAëƬѹۿ |
þseƷһӰԺ |
þþŷղa
|
ŷҹAŴƬþ |
þóۺɫۺ |
þ97þ97Ʒӿ |
þþƷaĻ |
þþ뾫Ʒҹ |
99ƷþþƷ |
ٸ߳ҽоþþþþ |
ĻhdþþƷ
|
ݺɫþ |
ŷͽxxxxѿþþ |
žžþ99ۺһ |
רþۺϾĻ
|
ݺɫþþһ |
һƷ˾þ |
ۺϾþü |
Ůþþ |
þùƷ-þþƷ |
˸ŮѲžþþ |
þۺϾƷ |
һ˾þþƷ |
һƷ˾þ |
ŷպƷþ
|
Ʒһþ㽶߿ |
þۺϸϾþúݺݺ97ɫ69 |
þþƷAVþþ |
ƷۺϾþþþþ98 |
þþƷ99þ |
69ۺϾþþƷ |