??xml version="1.0" encoding="utf-8" standalone="yes"?>久久久久久亚洲Av无码精品专口
,久久福利片,岛国搬运www久久 http://www.shnenglu.com/nacci/被约束的日日夜夜Q停不下来的旉?/description>zh-cn Wed, 07 May 2025 01:21:51 GMT Wed, 07 May 2025 01:21:51 GMT 60 归来 http://www.shnenglu.com/nacci/archive/2010/02/14/107732.htmlnacci nacci Sun, 14 Feb 2010 13:00:00 GMT http://www.shnenglu.com/nacci/archive/2010/02/14/107732.html http://www.shnenglu.com/nacci/comments/107732.html http://www.shnenglu.com/nacci/archive/2010/02/14/107732.html#Feedback 0 http://www.shnenglu.com/nacci/comments/commentRss/107732.html http://www.shnenglu.com/nacci/services/trackbacks/107732.html 距离上一博客,已经三年有余。值得庆幸的是Q现在自׃旧保持着对于底层技术知识的执着和热情,自己仍旧走在底层技术探索和研究的\上。尽已l越来越多的从事理工作Q我却一直都不断的提醒自己,技术是自己的灵,像我曾l因为技术取向上的与众不同而有了现在这份工作一栗?br> q前QJeffrey找我谈过Q关于职业取向上的想法。仔l想了想Q我仍然惛_技术道路上走得更远Q在底层技术上走得更远。尽各U反面的x和现实摆在眼前,但是Q我希望自己始终能有一颗勇于创造的内心?br> 新的一q_自己要更加努力,q是让自ql写下去吧,让写作成ZU坚持,让学习成ZU习惯,让分享成ZU快乐,让责LZU现实?/p>
]]> 假如 http://www.shnenglu.com/nacci/archive/2006/05/23/7541.htmlnacci nacci Tue, 23 May 2006 12:01:00 GMT http://www.shnenglu.com/nacci/archive/2006/05/23/7541.html http://www.shnenglu.com/nacci/comments/7541.html http://www.shnenglu.com/nacci/archive/2006/05/23/7541.html#Feedback 1 http://www.shnenglu.com/nacci/comments/commentRss/7541.html http://www.shnenglu.com/nacci/services/trackbacks/7541.html 人是需要拿动和真诚来证明自已的,q去的得׃能用假如来挽回和补救,只能用h生中的现实和眼前的时光甚至以后一生的旉努力M?q是Z断进?不断向上所要付出的一U代仗 ?br /> 所以我q是要说,不要在假如之后再假设有如?人生Ҏ(gu)没有假如Q ?br /> 所以我要说,我在假如之后,都是在认真的Ҏ(gu)错误,以求自已更快更好地接q我自已心目中的完美! ]]> d http://www.shnenglu.com/nacci/archive/2006/05/23/7520.htmlnacci nacci Mon, 22 May 2006 16:22:00 GMT http://www.shnenglu.com/nacci/archive/2006/05/23/7520.html http://www.shnenglu.com/nacci/comments/7520.html http://www.shnenglu.com/nacci/archive/2006/05/23/7520.html#Feedback 1 http://www.shnenglu.com/nacci/comments/commentRss/7520.html http://www.shnenglu.com/nacci/services/trackbacks/7520.html
DKP 记录里我们辉煌的瞬间Q想起了以往的种U的感动Q尽这U感觉不能永d_却在我心里划上了一C痕?span lang="EN-US">
很想再写Q却已无语,因ؓ心里真的承受不了q些回忆Q我很想像戒酒一h你戒掉,但我知道q是做不到的Q其实记忆会一直存在,所以请你要怿Q你一直在让我疼痛…?/span>
]]>MFC漫谈Q五Q——消息的路由Q?Q?/title> http://www.shnenglu.com/nacci/archive/2006/05/19/7395.htmlnacci nacci Fri, 19 May 2006 01:08:00 GMT http://www.shnenglu.com/nacci/archive/2006/05/19/7395.html http://www.shnenglu.com/nacci/comments/7395.html http://www.shnenglu.com/nacci/archive/2006/05/19/7395.html#Feedback 3 http://www.shnenglu.com/nacci/comments/commentRss/7395.html http://www.shnenglu.com/nacci/services/trackbacks/7395.html 阅读全文 ]]> MFC漫谈Q四Q——消息的路由 http://www.shnenglu.com/nacci/archive/2006/05/18/7365.htmlnacci nacci Thu, 18 May 2006 09:29:00 GMT http://www.shnenglu.com/nacci/archive/2006/05/18/7365.html http://www.shnenglu.com/nacci/comments/7365.html http://www.shnenglu.com/nacci/archive/2006/05/18/7365.html#Feedback 2 http://www.shnenglu.com/nacci/comments/commentRss/7365.html http://www.shnenglu.com/nacci/services/trackbacks/7365.html 有了消息映射表,如何利用呢?消息如何被分门别cȝz֏出去的? 用最基本的一句话概述Q钩子函数v了很大作用。故事是q样的,有些漫长Q也需要些耐心?br /> MFC中消息分?c: 1. WM_COMMAND Q所有的UIlg和加速键都会产生q种消息Q所有派生于CCmdTarget的类都有能力处理该消?br /> 2. 标准消息 Q除WM_COMMAND之外的WM_xx消息都是标准消息Q派生于CWnd的类都有能力处理该消?br /> 3. 控g通知消息 Q用于子H口控g向父H口发送的消息
在MFC的消息映表的徏立中Q通过一l宏Q你可以让自己的类先于父类处理某些Windows消息Q这U行为很像虚函数Q只是我们重载的内容不是虚函敎ͼ而是消息?/font>
推动消息的܇ W一阶段 H口q程 在生一个窗口的时候,会调用CFrameWnd::CreateQ所有的故事也都从这里展开。下面的代码Zz,L了不相关的代?br />
BOOL CFrameWnd::Create(?
{
//
?/span>
if
(
!
CreateEx(?)
{
//
?/span>
}
//
?/span>
}
BOOL CWnd::CreateEx(?
{
//
?/span>
AfxHookWindowCreate(
this
); HWND hWnd
=
::CreateWindowEx(?;
//
?/span>
}
void
AFXAPI AfxHookWindowCreate(CWnd
*
pWnd)
{
//
?/span>
if
(pThreadState
->
m_hHookOldCbtFilter
==
NULL)
{ pThreadState
->
m_hHookOldCbtFilter
=
::SetWindowsHookEx(WH_CBT, _AfxCbtFilterHook, NULL, ::GetCurrentThreadId());
//
?/span>
}
//
?/span>
pThreadState
->
m_pWndInit
=
pWnd; }
q样Q通过AfxHookWindowCreateQ在当前U程中安装了一个钩子,用来拦截和窗口相关的事gQ每当: 1. 另一个窗口成为activeQ?br />2. 产生或摧毁一个窗?br />3. Minimize或maximize一个窗口; 4. Ud或羃放一个窗口; 5. 完成一个来自系l菜单的命oQ?br />6. 从系l队列中取出一个消息; Ӟ都会先调用_AfxCbtFilterHookQ接下来看看钩子函数作了什么:
LRESULT CALLBACK _AfxCbtFilterHook(
int
code, WPARAM wParam, LPARAM lParam)
{
//
?/span>
WNDPROC afxWndProc
=
AfxGetAfxWndProc(); oldWndProc
=
(WNDPROC)SetWindowLongPtr(hWnd, GWLP_WNDPROC,(DWORD_PTR)afxWndProc);
//
?/span>
}
WNDPROC AFXAPI AfxGetAfxWndProc()
{
//
?/span>
return
&
AfxWndProc; }
q样Q_AfxCbtFilterHook的工作ȝh是通过H口子类化,把新建的H口的窗口过E设|成AfxWndProc?br />到这里,我们l于扑ֈ了窗口过E?br />l论 CFrameWnd::Create创徏H口调用CWnd::CreateEx CWnd::CreateEx调用AfxHookWindowCreate准备为窗口设|钩?br />AfxHookWindowCreate调用::SetWindowHookEx为窗口设|了一个WH_CBTcd的钩子来qo消息Qƈ把过滤函数设|成_AfxCbtFilterHook _AfxCbtFilterHook通过H口子类化设|窗口的H口q程为AfxWndProc q样Q通过::DispatchMessage发送给H口的消息就会源源不断地送到AfxWndProc中来Q可以想刎ͼAfxWndProc利用MFC的消息映表Q分门别cȝҎ(gu)息进行分?br /> Q待l……)
]]> MFC漫谈Q三Q——消息映?/title> http://www.shnenglu.com/nacci/archive/2006/05/18/7363.htmlnacci nacci Thu, 18 May 2006 08:31:00 GMT http://www.shnenglu.com/nacci/archive/2006/05/18/7363.html http://www.shnenglu.com/nacci/comments/7363.html http://www.shnenglu.com/nacci/archive/2006/05/18/7363.html#Feedback 4 http://www.shnenglu.com/nacci/comments/commentRss/7363.html http://www.shnenglu.com/nacci/services/trackbacks/7363.html
MFC中的消息循环呢?我们熟?zhn)的switch……case……到哪里MQ?br />
在MFC中,消息的@环ƈ不是用switch……case……实现的Q它依赖于一张由E序自n定义的消息网?br /> 首先QMFC用一个名为AFX_MSGMAP_ENTRYl构来对消息的信息进行封装:
struct
AFX_MSGMAP_ENTRY
{ UINT nMessage;
//
windows message
UINT nCode;
//
control code or WM_NOTIFY code
UINT nID;
//
control ID (or 0 for windows messages)
UINT nLastID;
//
used for entries specifying a range of control id's
UINT_PTR nSig;
//
signature type (action) or pointer to message #
AFX_PMSG pfn;
//
routine to call (or special value)
}
;
其中 typedef void (AFX_MSG_CALL CCmdTarget::*AFX_PMSG)(void); 之后Q通过一个链表,把这些描q消息的l构l织hQ构成消息映表的结构是AFX_MSGMAP
struct
AFX_MSGMAP
{
const
AFX_MSGMAP
*
pBaseMap;
const
AFX_MSGMAP_ENTRY
*
lpEntries; }
;
q样一个AFX_MSGMAP对象成了构建消息映表的关键h物,它一只手拉着基类的AFX_MSGMAP对象Q另一只手拉着cLw的消息映射表,q样只要正确地在每一个类中都安插一个AFX_MSGMAP对象Q那么整个消息映表徏立v来了。那么,何ؓ正确呢?含义?Q一是正的讄pBaseMapQo它指向基c,二是正确的徏立类自n的消息映表。这两个工作是由4个宏完成的, 它们是:DECLARE_MEMSSAGE_MAP() / BEGIN_MESSAGE_MAP() / ON_COMMAND()Q注QON_COMMAND宏只是ؓ了处理命令消息,对于其它的消息还有对应的宏,但是原理是相同的Q?/ END_MESSAGE_MAP()?br />让我们一个个的看看:
#define
DECLARE_MESSAGE_MAP() \
private
: \
static
const
AFX_MSGMAP_ENTRY _messageEntries[]; \
protected
: \
static
const
AFX_MSGMAP messageMap; \
virtual
const
AFX_MSGMAP
*
GetMessageMap()
const
; \
q个宏的作用?Q?br /> 1. 在类中插入一个静态成员_messageEntriesQ这是用来存攄要处理的消息的数l(即类本n的消息映表Q?br /> 2. 另一个静态成员massageMap用来指向基类的消息映表 3. 安插一个虚函数Q其内容有待实现
接下来,_messageEntries的初始化QmessageMap的正指向,GetMessageMap函数的实现这些工作还都没做,那正是后三个宏的责QQ它们要序使用Q方能工作正常?
#define
BEGIN_MESSAGE_MAP(theClass, baseClass) \
const
AFX_MSGMAP
*
theClass::GetMessageMap()
const
\
{
return
&
theClass::messageMap; }
\ AFX_COMDAT
const
AFX_MSGMAP theClass::messageMap
=
\
{
&
baseClass::messageMap,
&
theClass::_messageEntries[
0
] }
; \ AFX_COMDAT
const
AFX_MSGMAP_ENTRY theClass::_messageEntries[]
=
\
{ \
q个宏的作用?Q?br />1. 定义了安插在cM的虚函数GetMessageMap()Q只是简单的q回messageMap对象的地址 2. 初始化messageMapQ把zcd基类联系h构成一个大的消息映表 3. 为类本n的消息映表的初始化做语法准?/font>
ON_COMMANDq个宏的作用是向_messageEntries数组中添加类本n要处理的命o消息Q其实在MFC中还有很多更方便的宏可以向类中添加消息,例如OM_WM_PAINT{,q里Q我们主要讨论ON_COMMANDQ毕竟原理都是相同的?br />
#define
ON_COMMAND(id, memberFxn) \
{ WM_COMMAND, CN_COMMAND, (WORD)id, (WORD)id, AfxSigCmd_v, \ static_cast
<
AFX_PMSG
>
(memberFxn) }
,
无非是对AFX_MSG_ENTRYl构的初始化Q这样在cM为每一个想要处理的消息都是用一个ON_COMMAND宏,p动的初始化了cLw的消息映射表?/font>
最后,当全部的信息d完毕后,使用END_MESSAGE_MAP()宏通知MFC一个类消息映射表结束了?br />
#define
END_MESSAGE_MAP() \
{
0
,
0
,
0
,
0
, AfxSig_end, (AFX_PMSG)
0
}
\ }; \
实现手法单纯得很Q无非是一个全0的AFX_MESSAGE_MAP对象?br />
l论
惌让你的类处理某个消息Q用下面的l合Q?/font>
BEGIN_MESSAGE_MAP(theClass, the
base
Class)
//
消息处理?/span>
END_MESSAGE_MAP()
Q待l……)
]]> MFC漫谈Q二Q——对象的动态创?/title> http://www.shnenglu.com/nacci/archive/2006/05/18/7355.htmlnacci nacci Thu, 18 May 2006 08:07:00 GMT http://www.shnenglu.com/nacci/archive/2006/05/18/7355.html http://www.shnenglu.com/nacci/comments/7355.html http://www.shnenglu.com/nacci/archive/2006/05/18/7355.html#Feedback 0 http://www.shnenglu.com/nacci/comments/commentRss/7355.html http://www.shnenglu.com/nacci/services/trackbacks/7355.html
接上ơRTTI的话题?br /> 能够在运行时发现一个对象的cdQ就可以在运行时动态的创徏一个对象。在一个类库中Q拥有统一的对象创建方式是非常重要的?br />
在MFC中,对象的动态创依赖于RTTI所建立h的类别型录,和动态创建有关的CRuntimeClass成员有两个:
CObject * (PASCAL * m_pfnCreateObject)(); // 指向用于创徏对象的函?/span>CObject * CreateObject(); // 利用m_pfnCreateObject创徏对象 利用RTTI建立的类别型录,DECLARE_DYNCREATE / IMPLEMENT_DYNCREATEl箋为类d了动态创建的功能?/p>
#define DECLARE_DYNCREATE (class_name) \ DECLARE_DYNAMIC (class_name) \ static CObject * PASCAL CreateObject(); q个宏同L在类声明中,它不但ؓcL加了class##class_name对象和GetRuntimeClass()Q还为类加入了一个静态函数CreateObject,用来q行对象的动态创建。同样IMPLEMENT_DYNCREATE用来对上面添加的内容作定义和初始化工作?/p>
#define IMPLEMENT_DYNCREATE (class_name, base_class_name) \ CObject* PASCAL class_name::CreateObject() \ { return new class_name; } \ IMPLEMENT_RUNTIMECLASS (class_name, base_class_name, 0xFFFF , \ class_name::CreateObject, NULL) 和IMPLEMENT_DYNAMIC不同的是Q这里的IMPLEMENT_RUNTIMECLASS中的W?个参数ƈ不ؓNULLQ而是class_name::CreateObjectQ这样就指定了用于创建对象的函数Q至于其它的内容Q与RTTI没有什么不同?br /> 于是Q整个对象的动态创E就变得非常单了Q只要我们找到某个特定类的CRuntimeClass对象Q利用class##class_name.CreateObject()可以了?/p>
CObject * CRuntimeClass::CreateObject() { CObject * pObject = NULL; pObject = ( * m_pfnCreateObject)(); return pObject; } l论 惌你的cdMFC中支持动态创建, 1. 在类声明中用DECLARE_DYNAMIC 2. 在类定义文g中用IMPLEMENT_DYNAMICQ此?br /> class##class_name.m_pfnCreateObject = class_name::CreateObject; CRuntimeClass::CreateObject利用m_pfnCreateObject可以进行对象的动态创Z Q待l……)
]]> MFC漫谈Q一Q——RTTI http://www.shnenglu.com/nacci/archive/2006/05/18/7350.htmlnacci nacci Thu, 18 May 2006 06:53:00 GMT http://www.shnenglu.com/nacci/archive/2006/05/18/7350.html http://www.shnenglu.com/nacci/comments/7350.html http://www.shnenglu.com/nacci/archive/2006/05/18/7350.html#Feedback 1 http://www.shnenglu.com/nacci/comments/commentRss/7350.html http://www.shnenglu.com/nacci/services/trackbacks/7350.html 所有的q一pd的东襉K来源于前天晚上的一个电(sh)话,内容大概是说Q?/span>
?/span>
你能教会我一个让我对
MFC
有点感觉?/span>
Hello World
吗?我望一个像?/span>
C
写的
Win32 Hello World
一L观的例子?/span>
?/span>
xq曾l是我学?/span>
MFC
的时候也惛_q的问题。我是一个喜Ƣ刨栚w底的人,喜欢把事情搞明白Q于是曾l很长的一D|间里Q我都困惑在UL杂ؕ的代码里。现在回惌v来,侯捷老师的?/span>
Dessecting MFC
》和
Jeff Prosise
的?/span>
Programming MFC
》一赯来,估计能达到解惑的目的。当Ӟ需要的是一点点耐心和对
Win32
E序的一Ҏ(gu)基本的了解(貌似废话。。。)。于是那天晚上,
QQ
上和那个朋友聊了挺长一D|_腾了一?/span>
MFC
的源代码Q就有了q一pd的东西,全当是故地重怺一番。言归正传吧。文章中所有的代码都提取自MFC 7.0在MFC中,RTTI是依靠ؓ彼此有承关pȝcd立一个记录其cd的链表来实现的,和RTTI有关的CRuntimeClass成员?个:LPCSTR m_lpszClassName; // 用于记录cd // 用于指向基类的CRuntimeClassl构 CRuntimeClass * m_pBaseClass; // 用于指向链表中前一个类的CRuntimeClassl构 CRuntimeClass * m_pNextClass; // 用于建立cd型录 const AFX_CLASSINIT * m_pClassInit; q样在这个类别型录中有了许多条路径Q每一条都是沿着m_pBaseClass一直可以找到某个类的最l基cR要把一个类加入到这个类别型录中要用C个宏Q?br />DECLARE_DYNAMIC / IMPLEMENT_DYNAMIC 其中Q?br />#define DECLARE_DYNAMIC (class_name) \ public : \ static const CRuntimeClass class ##class_name; \ virtual CRuntimeClass * GetRuntimeClass() const ; \ q个宏是用在cd明中的,其作用就是根据类的名字ؓ该类d两个public的成员,分别用于记录cȝ型别和获得对象class##class_name的地址Q注意这里的class##class_name是个静态成员,q就为后面我们做cd的比较奠定了基础Q承于同一个基cȝzcd象包含共同的静态类成员Q。在cM使用了DECLARE_DYNAMIC后,q要?cpp的文件中使用IMPLEMENT_DYNAMIC宏,该宏的作用就是初始化class##class_name对象和定义GetRuntimeClass函数?br />#define IMPLEMENT_DYNAMIC (class_name, base_class_name) \ IMPLEMENT_RUNTIMECLASS (class_name, base_class_name, 0xFFFF , NULL, NULL) IMPLEMENT_DYNAMIC在用的时候,要指定类和其基类的名字,之后利用IMPLEMENT_RUNTIMECLASSq行实质性的初始化活动?br />#define IMPLEMENT_RUNTIMECLASS (class_name, base_class_name, wSchema, pfnNew, class_init) \ AFX_COMDAT const CRuntimeClass class_name:: class ##class_name = { \ #class_name, sizeof ( class class_name), wSchema, pfnNew, \ RUNTIME_CLASS(base_class_name), NULL, class_init } ; \ CRuntimeClass * class_name::GetRuntimeClass() const \ { return RUNTIME_CLASS (class_name); } \ 其中Q在class#class_name的初始化中和RTTI相关的只有: &name_class用来初始化m_lpszClassName RUNTIME_CLASS(base_class_name)用来初始化CRuntimeClass* m_pBaseClass NULL用来初始化CRuntimeClass* m_pNextClassQ此时类别型录还没有建立hQ?
另外QRUNTIME_CLASS是用来获得class##class_name对象地址的宏Q?br />
#define RUNTIME_CLASS (class_name) _RUNTIME_CLASS (class_name) #define _RUNTIME_CLASS (class_name) \ ((CRuntimeClass* ) ( & class_name:: class ##class_name)) q样Q当对程序中的每一个类都用了DECLARE_DYNAMIC / IMPLEMENT_DYNAMIC宏之后,׃ؓ该类在类别型录中q行了登记工作。当ӞMFC中所有的c都z于CObjectQ所以所有的路线最l都要在CObject处会合,׃CObject没有基类Q所以它的CRuntimeClass对象q不能用上面的两个宏来实玎ͼ在objcore.cpp中,为CObject的classCObject对象单独作了初始化的工作Q?/p>
const struct CRuntimeClass CObject::classCObject = { " CObject " , sizeof (CObject), 0xffff , NULL, NULL, NULL } ; 我们可以看到m_pBaseClass被初始化为NULL。另外,也单独实CGetRuntimeClass():
CRuntimeClass * CObject::GetRuntimeClass() const { return _RUNTIME_CLASS (CObject); } 至于_RUNTIME_CLASSQ前面已l说q了。这P如果惌把自qcMl给MFCQ只要在cd明中使用DECLARE_DYNAMICQ在cȝ实现中加入IMPLEMENT_DYNAMIC Q就可以把自己注册到cd型录中了。至此,Z实现cd象的RTTIQ我们已l做好了所有的准备工作Q下面就来看一下它的实玎ͼ它主要是靠CObject中的IsKindOf函数完成的?/p>
BOOL CObject::IsKindOf( const CRuntimeClass * pClass) const { // Zz,略去了不相关的代?/span> CRuntimeClass * pClassThis = GetRuntimeClass(); return pClassThis -> IsDerivedFrom(pClass); } q里Q由于GetRuntimeClass是虚函数Q所以pClassThis会指向调用IsKindOf函数的类对象的class##class_nameQ之后利用指向该对象的指针调用IsDerivedFromQ?/p>
BOOL CRuntimeClass::IsDerivedFrom( const CRuntimeClass * pBaseClass) const { // Zz,略去了不相关的代?/span> if (pBaseClass == NULL) return FALSE; // simple SI case const CRuntimeClass * pClassThis = this ; while (pClassThis != NULL) { if (pClassThis == pBaseClass) return TRUE; pClassThis = pClassThis -> m_pBaseClass; } return FALSE; // walked to the top, no match } 我们知道Q派生类和基cd享基cȝstatic对象Q所以在q里Q派生类和基cM定共享相同的class##class_name对象Q这׃ؓ我们判定两个cL否有l承关系提供了理论基Q同P在IsDerivedFrom中,while循环中的if也的是q样做的Q它沿着该类的同宗\U上行,只要不到共同的祖先CObjectQ就决不|休。 l论 如果惌把自qcMl给MFCQ只要在cd明中使用DECLARE_DYNAMICQ在cȝ实现中加入IMPLEMENT_DYNAMIC Q就可以把自己注册到cd型录中了。 Q待l……)
]]> 回家 http://www.shnenglu.com/nacci/archive/2006/05/16/7246.htmlnacci nacci Tue, 16 May 2006 05:02:00 GMT http://www.shnenglu.com/nacci/archive/2006/05/16/7246.html http://www.shnenglu.com/nacci/comments/7246.html http://www.shnenglu.com/nacci/archive/2006/05/16/7246.html#Feedback 4 http://www.shnenglu.com/nacci/comments/commentRss/7246.html http://www.shnenglu.com/nacci/services/trackbacks/7246.html
一ơ工会经历的坎坷惛_的?br /> dQ是一个过E;回家Q是一个过E。开门、关门,q些属于生命里的情节。每日每月每q都有h生的舞台上演出,直到生命的舞台拉下大q?br /> 初离家时的那U感觉让人刻苦铭心。不要说d的理由,为逃避q还是ؓ谋生。我d了,背v行囊Q在心中暗暗发一回誓Q然后头也不回地走在不知廷C方的路。尽知道有x的眼睛牵着q去的n影,可还是走下去。走得远?走得累了Q才知道家是圆心Q而我们无论到何时都是圆上的一个点Q我们离家越q,家对我们的离心率p大。我们在茫茫人v中沉、挣扎,如一只在茫茫风雨中寻觅谷_的鸟Q深感自q渺小Q这时才感到家的温暖与安全。我们在d的时候义无反,可是d后,我们又如相思的(zhn)者在心中看着Ӟ才知道家是我们一生的渴望?br /> 回家是一U求的心情Q那U心情,是离家的延箋。被风雨z礼后的船刻满大L刀痕,帆破了。船漏了Q水手也乏了。只有此时我们才能体会出归心似箭q个词的份量。就如飞倦的鸟儿惌扑ֈ自己的l(f)Q折了翅膀在风雨中痛苦地搏d觅,惌紧张的神l放个假Q让疲惫的精歇一歇。推门的一刚wQ貌的洒脱,骨子里却有与生俱来的软弱与疲乏。本惛_家诉说遭受的创伤和委屈,却满脸写着春风得意的笑容与成功的自豪。你t掉鞋子光着脚在地板上走来走去,你看Cd时点着的蜡烛还在燃烧,你离家时打开的那本书q放在桌上。你一会儿看看书,一会儿喝几口茶或工炚w食吃Q你在温暖中睡一个温馨的觉,攒到_的力量?br /> 留下 希望w边的每个h留下 每个人的内心都有脆弱的角?br />现在Q请听我?br />因ؓ我已l成Z伤害你心늚?br />注定要承受心灵孤单的这D|?br />感谢大家q去做过的一?br />那些丽已经永存于心 在我的记忆里Q强烈望和d说再?br />心里攑֣痛哭 因ؓ真的很难说再?br />看着你们伸出双手 我相信你们能明白我的心情 Z自己的心情,扑ֈ自己的目?br />不经意掉落的泪水 z溢的爱的光?br />因ؓq里承蝲着我们现实的梦?br />在那些最亲爱的记忆里 有我们一起创造的奇迹 感受C心灵的呼?br />从远方传来的声音Q声Cl?br />那是生命的旋?br />曄的声音今天成了美妙的旋律 盘桓在心_久到我们失去记忆 即便是那? 我相信,我依旧可以喊?恋爱之家+q个名字Q?/font>
]]> 在编译时军_cd的可l承?/title> http://www.shnenglu.com/nacci/archive/2006/05/15/7200.htmlnacci nacci Mon, 15 May 2006 09:20:00 GMT http://www.shnenglu.com/nacci/archive/2006/05/15/7200.html http://www.shnenglu.com/nacci/comments/7200.html http://www.shnenglu.com/nacci/archive/2006/05/15/7200.html#Feedback 0 http://www.shnenglu.com/nacci/comments/commentRss/7200.html http://www.shnenglu.com/nacci/services/trackbacks/7200.html
2 个类?span lang="EN-US">U ?span lang="EN-US">TQ你如何来确?span lang="EN-US">U是否l承?span lang="EN-US">T呢?在编译时发现两个cd的这U关pd于泛型库的优化是极ؓ重要的。在泛型函数中,如果某个cdC特定的接口,你可以根据这U关pMؓ其利用特定的优化法。另外,如果我们可以在编译期军_2 个类的关p,我们也可以远?span lang="EN-US">dynamic_castQ从而避免运行时的效率开销?br />
2 个Q意类?span lang="EN-US">U?span lang="EN-US">TQ如何确?span lang="EN-US">T能否自动转换?span lang="EN-US">U呢?
sizeof 用在M复杂的表辑ּ上, sizeof 可以q回q个表达式值的大小Q而不会在q行时评估表辑ּ的倹{这也就意味着Q你可以把函数重载、模版实例化、{换规则等{所有你可以?span lang="EN-US">C++表达式中使用的设施统l塞?span lang="EN-US">sizeof中来。实际上Q?span lang="EN-US">sizeof隐藏了一个可以演l表辑ּcd的设施,最l,sizeof 会返回表辑ּl果的类型?span lang="EN-US">
sizeof 和重载函数来解决判断cd之间的可转换性的问题。思\很简单:我们提供2 个重载函敎ͼ一个函数的参数是我们要转换成的cdQ我们用U 表示Q,而另一个则用来接收其他所有类型的参数。然后我们把要检的cdQ用T 表示Q传递给重蝲函数。如果接受类?span lang="EN-US">U为参数的函数被调用了Q我们就认ؓT 可以转换?span lang="EN-US">UQ反之则不可以。如何确定哪个函数被调用了呢Q我们利?span lang="EN-US">sizeof出马Q我们只要让重蝲函数q回不同的类型,然后查一下返回值就可以了?span lang="EN-US">
2 个不同的cdQ?span lang="EN-US">
typedef
char
Small;
class
Big
{
char
dummy[
2
]; }
;
默认情况下,
sizeof(Small)
?/span>
1
Q?/span>
Big
的大则无关紧要Q我们只要知道肯定不?/span>
1
好了?/span>
其次Q定?/span>
2
个重载函敎ͼ一个接收要转换成的cdQ?/span>
Small Test(U);
另一个用来接收“其他的所有类型”,我们要保证在排除所有的转换之后才调用这个函敎ͼ
OK,
用省略号表示的参数列表真好满需?/span>
Big Test(...);
管把一?/span>
C++
对象传递给
...
参数cd的函敎ͼ其结果未定义Q但是实际上我们q没有调用这个函数。我们甚臛_以不用实现它?/span>
最后,我们?/span>
sizeof
判断一下就完成d了:
const
bool
convExist
=
sizeof
(Test(T()))
==
sizeof
(Small);
你也怼_是它了Q?/span>
Test
的调用会创徏一个时对?/span>
T
Q之后可能的l果只能?/span>
sizeof(Small)
?/span>
sizeof(Big)
。兴奋之余,我们q要看到一个问题。如?/span>
T
的构造函数被设计?/span>
private
Q我们就前功弃了。当然解决的Ҏ(gu)也很单,定义一个函敎ͼ让他q回cd?/span>
T
的对象?/span>
T MakeT();
const
bool
convExist
=
sizeof
(Test(MakeT()))
==
sizeof
(Small);
最后,把刚才的东西装C个类里:
template
<
class
T,
class
U
>
class
Conversion
{ typedef
char
Small;
class
Big
{
char
dummy[
2
]; }
;
static
Small Test(U);
static
Big Test( );
static
T MakeT();
public
:
enum
{ exist
=
sizeof
(Test(MakeT()))
==
sizeof
(Small) }
; }
;
另外Q我们还可以讄另外一个常?/span>
Conversion::SameType
Q如?/span>
T
?/span>
U
表示同一个类型,那么q回
true
Q?/span>
template
<
class
T,
class
U
>
class
Conversion
{ ..
as
above..
enum
{ sameType
=
false
}
}
;
之后为同一个类型设计一个偏特化版本Q?/span>
template
<
class
T
>
class
Conversion
<
T, T
>
{
enum
{ exists
=
1
, sameType
=
1
}
; }
;
最后,回到我们的主题,通过
Conversion
的帮助,我们可以来决定两个类型的l承性了?/span>
#define
SUPERSUBCLASS(T, U) \
(Conversion
<
const
U
*
,
const
T
*
)::exists
&&
\
!
Conversion
<
const
T
*
,
const
void
*>
::sameType)
?/span>
U
l承?/span>
T
或?/span>
U
?/span>
T
是同一个类型的时候,
SUPERSUBCLASS
q回
true
。ȝ一下,只有下面q?/span>
3
U情?/span>
const U*
可以隐式转换?/span>
const T*
Q?/span>
1.
T
?/span>
U
是同一个类?/span>
2.
T
?/span>
U
的Q意一个基c?/span>
3.
T
?/span>
void
我们通过W?/span>
2
个测试屏蔽了最后一U情形。当Ӟ如果你认为同一U类型也不算是承关pȝ话,可以q一步严格其条gQ?/span>
#define
SUPERSUBCLASS_STRICT(T, U) \
(SUPERSUBCLASS(T, U)
&&
\
!
Conversion(
const
T,
const
U)::sameType)
]]>
ŷ츾XXXXԾþþ |
ҹþþþüŮӰԺ |
þҹӰԺѹۿ |
2019þþø456 |
þþþ99ƷƬëƬ |
þùƷǿ |
þùŷպƷ
|
þþŮһ |
þҹƵ |
¾þƵ |
þˬˬƬav鷳
|
Ʒһþ㽶߿ۿ
|
þþWWWѾƷ |
þAAAAƬһ |
þӰ |
ŷƷþø |
þҹƵ |
Ļþ |
þþƷAV |
Ʒþù鶹99վ |
˺ݺۺϾþ88 |
þþþӰԺС |
ĻhdþþƷ
|
þһձɫۺϾþ |
þþþAVƬ |
þ99ëƬѹۿ
|
ŷþþþþþ |
ȾþùþƷ |
þۺɫˮ99ž |
ŮþþŮ |
99þþƷ |
ɫ͵͵88ŷƷþþ |
ɫþþۺľþav |
Ʒþþþþþþ
|
˾þô߽AVɫɫ |
99þ뾫Ʒϵ |
þþƷһӰԺ |
˳ŷþ |
þ99Ƶ |
ƷŮ߳þþ |
Сڵþþþþ |