﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-牧光小院</title><link>http://www.cppblog.com/nacci/</link><description>被约束的日日夜夜，停不下来的时间。</description><language>zh-cn</language><lastBuildDate>Sun, 05 Apr 2026 16:40:27 GMT</lastBuildDate><pubDate>Sun, 05 Apr 2026 16:40:27 GMT</pubDate><ttl>60</ttl><item><title>归来</title><link>http://www.cppblog.com/nacci/archive/2010/02/14/107732.html</link><dc:creator>nacci</dc:creator><author>nacci</author><pubDate>Sun, 14 Feb 2010 13:00:00 GMT</pubDate><guid>http://www.cppblog.com/nacci/archive/2010/02/14/107732.html</guid><wfw:comment>http://www.cppblog.com/nacci/comments/107732.html</wfw:comment><comments>http://www.cppblog.com/nacci/archive/2010/02/14/107732.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/nacci/comments/commentRss/107732.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/nacci/services/trackbacks/107732.html</trackback:ping><description><![CDATA[<p style="FONT-SIZE: 10pt">距离上一篇博客，已经三年有余。值得庆幸的是，现在自己仍旧保持着对于底层技术知识的执着和热情，自己仍旧走在底层技术探索和研究的路上。尽管已经越来越多的从事管理工作，我却一直都不断的提醒自己，技术是自己的灵魂，就像我曾经因为技术取向上的与众不同而有了现在这份工作一样。<br><br>年前，Jeffrey找我谈过，关于职业取向上的想法。仔细想了想，我仍然想在技术道路上走得更远，在底层技术上走得更远。尽管各种反面的想法和现实摆在眼前，但是，我希望自己始终能有一颗勇于创造的内心。<br><br>新的一年，自己要更加努力，还是让自己继续写下去吧，让写作成为一种坚持，让学习成为一种习惯，让分享成为一种快乐，让责任成为一种现实。</p>
<img src ="http://www.cppblog.com/nacci/aggbug/107732.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/nacci/" target="_blank">nacci</a> 2010-02-14 21:00 <a href="http://www.cppblog.com/nacci/archive/2010/02/14/107732.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>假如</title><link>http://www.cppblog.com/nacci/archive/2006/05/23/7541.html</link><dc:creator>nacci</dc:creator><author>nacci</author><pubDate>Tue, 23 May 2006 12:01:00 GMT</pubDate><guid>http://www.cppblog.com/nacci/archive/2006/05/23/7541.html</guid><wfw:comment>http://www.cppblog.com/nacci/comments/7541.html</wfw:comment><comments>http://www.cppblog.com/nacci/archive/2006/05/23/7541.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/nacci/comments/commentRss/7541.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/nacci/services/trackbacks/7541.html</trackback:ping><description><![CDATA[        <font size="2"> 人是需要拿出行动和真诚来证明自已的,过去的得失不能用假如来挽回和补救,只能用人生中的现实和眼前的时光甚至以后一生的时间努力去争取,这是人不断进步,不断向上所要付出的一种代价。  <br />          所以我还是要说,不要在假如之后再假设有如果,人生根本没有假如；  <br />          所以我要说,我在假如之后,都是在认真的改正错误,以求自已更快更好地接近我自已心目中的完美!  <br /></font><img src ="http://www.cppblog.com/nacci/aggbug/7541.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/nacci/" target="_blank">nacci</a> 2006-05-23 20:01 <a href="http://www.cppblog.com/nacci/archive/2006/05/23/7541.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>离开</title><link>http://www.cppblog.com/nacci/archive/2006/05/23/7520.html</link><dc:creator>nacci</dc:creator><author>nacci</author><pubDate>Mon, 22 May 2006 16:22:00 GMT</pubDate><guid>http://www.cppblog.com/nacci/archive/2006/05/23/7520.html</guid><wfw:comment>http://www.cppblog.com/nacci/comments/7520.html</wfw:comment><comments>http://www.cppblog.com/nacci/archive/2006/05/23/7520.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/nacci/comments/commentRss/7520.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/nacci/services/trackbacks/7520.html</trackback:ping><description><![CDATA[
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt">
				<span style="FONT-SIZE: 10pt; FONT-FAMILY: 新宋体">寂静的夜晚，忧郁的歌声……<br /><br /><span lang="EN-US"><?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /?><o:p></o:p></span></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt">
				<span style="FONT-SIZE: 10pt; FONT-FAMILY: 新宋体">我再次肯定了人们经常说的一话：也许真的要到了结束才知道去珍惜过往，去珍惜过去和大家在一起的时光。坦白说这次我走了，很疼，很痛苦，因为过去有太多的感动，太多的幸福。不知道是不是因为离别的时间越来越来近，现在的我们做什么好象都要加上“最后一次”，最后一次在工会里和大家说话，最后一次是恋爱之家的成员，最后一次看着工会里熟悉的面孔，最后一次…… <span lang="EN-US"><o:p></o:p></span></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span style="FONT-SIZE: 10pt; FONT-FAMILY: 新宋体">
						<br />　　我这段时间总是在想一个问题，我应该以什么样的方式去结束魔兽世界里的这段感情，又怎样去为它划上一个完美的句号。我不知道，也不敢在往下想，因为我真的已经习惯了这样的日子。现在的我，心情是复杂的，其实我早该预料到我们最终会走向这么一结局，我应该顺其自然些，但一些事情又何止是“顺其自然”四个字这么简单。<span lang="EN-US"><o:p></o:p></span></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span style="FONT-SIZE: 10pt; FONT-FAMILY: 新宋体">
						<br />　　今天，我终于走了，不过与我想象中的有所不同，我前不久还在想怎样去划上这个句号，今天却……可不管是怎样的，结果却永远不会变，我走了，就这样的走了，最后还是要跟大家说声“对不起”，现在的我很难过，这样的离别让我背上了太多的伏罪感，脑海里回放着过去的点点滴滴，看着<span lang="EN-US">DKP</span>记录里我们辉煌的瞬间，想起了以往的种种的感动，尽管这种感觉不能永驻心间，却在我心里划上了一到伤痕。<span lang="EN-US"><o:p></o:p></span></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span style="FONT-SIZE: 10pt; FONT-FAMILY: 新宋体">
						<br />　　我们一起写的故事，后续已写不下去；<span lang="EN-US"><o:p></o:p></span></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 新宋体">
						<span style="mso-tab-count: 1">    </span>
				</span>
				<span style="FONT-SIZE: 10pt; FONT-FAMILY: 新宋体">已经没法再说更多的谎；<span lang="EN-US"><o:p></o:p></span></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 新宋体">
						<span style="mso-tab-count: 1">    </span>
				</span>
				<span style="FONT-SIZE: 10pt; FONT-FAMILY: 新宋体">说不出的寂寞，想求助的夜晚；<span lang="EN-US"><o:p></o:p></span></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 新宋体">
						<span style="mso-tab-count: 1">    </span>
				</span>
				<span style="FONT-SIZE: 10pt; FONT-FAMILY: 新宋体">我们一起写的故事，已经不需要加页；<span lang="EN-US"><o:p></o:p></span></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 新宋体">
						<span style="mso-tab-count: 1">    </span>
				</span>
				<span style="FONT-SIZE: 10pt; FONT-FAMILY: 新宋体">窗外月亮的光辉，照进孤独的房间；<span lang="EN-US"><o:p></o:p></span></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 新宋体">
						<span style="mso-tab-count: 1">    </span>
				</span>
				<span style="FONT-SIZE: 10pt; FONT-FAMILY: 新宋体">像被看穿一样，一直照到我心底；<span lang="EN-US"><o:p></o:p></span></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 新宋体">
						<span style="mso-tab-count: 1">    </span>
				</span>
				<span style="FONT-SIZE: 10pt; FONT-FAMILY: 新宋体">喜欢你的感觉，虽然现在也没有改变；<span lang="EN-US"><o:p></o:p></span></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 新宋体">
						<span style="mso-tab-count: 1">    </span>
				</span>
				<span style="FONT-SIZE: 10pt; FONT-FAMILY: 新宋体">但比起背叛心灵的痛苦，我选择离开。<span lang="EN-US"><o:p></o:p></span></span>
		</p>
		<span style="FONT-SIZE: 10pt; FONT-FAMILY: 新宋体; mso-font-kerning: 1.0pt; mso-bidi-font-family: 'Times New Roman'; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">
				<br />    很想再写，却已无语，因为心里真的承受不了这些回忆，我很想像戒酒一样把你戒掉，但我知道这是做不到的，其实记忆会一直存在，所以请你要相信，你一直在让我疼痛……</span>
<img src ="http://www.cppblog.com/nacci/aggbug/7520.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/nacci/" target="_blank">nacci</a> 2006-05-23 00:22 <a href="http://www.cppblog.com/nacci/archive/2006/05/23/7520.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>MFC漫谈（五）——消息的路由（2）</title><link>http://www.cppblog.com/nacci/archive/2006/05/19/7395.html</link><dc:creator>nacci</dc:creator><author>nacci</author><pubDate>Fri, 19 May 2006 01:08:00 GMT</pubDate><guid>http://www.cppblog.com/nacci/archive/2006/05/19/7395.html</guid><wfw:comment>http://www.cppblog.com/nacci/comments/7395.html</wfw:comment><comments>http://www.cppblog.com/nacci/archive/2006/05/19/7395.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.cppblog.com/nacci/comments/commentRss/7395.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/nacci/services/trackbacks/7395.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 继续上一个主题直线上溯的消息上次说到消息被转发到了AfxWndProc，继续。 LRESULT CALLBACKAfxWndProc(HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam) {    // …    // all other messages route through message map    CWnd* pWnd = CW...&nbsp;&nbsp;<a href='http://www.cppblog.com/nacci/archive/2006/05/19/7395.html'>阅读全文</a><img src ="http://www.cppblog.com/nacci/aggbug/7395.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/nacci/" target="_blank">nacci</a> 2006-05-19 09:08 <a href="http://www.cppblog.com/nacci/archive/2006/05/19/7395.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>MFC漫谈（四）——消息的路由</title><link>http://www.cppblog.com/nacci/archive/2006/05/18/7365.html</link><dc:creator>nacci</dc:creator><author>nacci</author><pubDate>Thu, 18 May 2006 09:29:00 GMT</pubDate><guid>http://www.cppblog.com/nacci/archive/2006/05/18/7365.html</guid><wfw:comment>http://www.cppblog.com/nacci/comments/7365.html</wfw:comment><comments>http://www.cppblog.com/nacci/archive/2006/05/18/7365.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cppblog.com/nacci/comments/commentRss/7365.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/nacci/services/trackbacks/7365.html</trackback:ping><description><![CDATA[
		<font size="2">有了消息映射表，如何利用呢？消息如何被分门别类的派发出去的？<br /><hr /><br />用最基本的一句话概述，钩子函数起了很大作用。故事是这样的，有些漫长，也需要些耐心。<br /><br />MFC中消息分为3类：<br /><br /><strong> 1. WM_COMMAND</strong>：所有的UI组件和加速键都会产生这种消息，所有派生于CCmdTarget的类都有能力处理该消息<br /><strong> 2. 标准消息</strong>：除WM_COMMAND之外的WM_xx消息都是标准消息，派生于CWnd的类都有能力处理该消息<br /><strong> 3. 控件通知消息</strong>：用于子窗口控件向父窗口发送的消息</font>
		<p>
				<font size="2">在MFC的消息映射表的建立中，通过一组宏，你就可以让自己的类先于父类处理某些Windows消息，这种行为很像虚函数，只是我们重载的内容不是虚函数，而是消息。</font>
		</p>
		<p>
				<font size="2">
						<strong>推动消息的泵<br /><br /></strong>第一阶段 窗口过程<br /><br />在产生一个窗口的时候，会调用CFrameWnd::Create，所有的故事也都从这里展开。下面的代码为了简洁，去掉了不相关的代码<br /></font>
		</p>
		<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee">
				<font size="2">
						<img id="Codehighlighter1_26_71_Open_Image" onclick="this.style.display='none'; Codehighlighter1_26_71_Open_Text.style.display='none'; Codehighlighter1_26_71_Closed_Image.style.display='inline'; Codehighlighter1_26_71_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" />
						<img id="Codehighlighter1_26_71_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_26_71_Closed_Text.style.display='none'; Codehighlighter1_26_71_Open_Image.style.display='inline'; Codehighlighter1_26_71_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align="top" />
						<span style="COLOR: #000000">BOOL CFrameWnd::Create(…) </span>
						<span id="Codehighlighter1_26_71_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">
								<img src="http://www.cppblog.com/images/dot.gif" />
						</span>
				</font>
				<span id="Codehighlighter1_26_71_Open_Text">
						<font size="2">
								<span style="COLOR: #000000">{<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    </span>
								<span style="COLOR: #008000">//</span>
								<span style="COLOR: #008000"> …</span>
						</font>
						<span style="COLOR: #008000">
								<br />
								<font size="2">
										<img id="Codehighlighter1_53_63_Open_Image" onclick="this.style.display='none'; Codehighlighter1_53_63_Open_Text.style.display='none'; Codehighlighter1_53_63_Closed_Image.style.display='inline'; Codehighlighter1_53_63_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" />
										<img id="Codehighlighter1_53_63_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_53_63_Closed_Text.style.display='none'; Codehighlighter1_53_63_Open_Image.style.display='inline'; Codehighlighter1_53_63_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />
								</font>
						</span>
						<font size="2">
								<span style="COLOR: #000000">    </span>
								<span style="COLOR: #0000ff">if</span>
								<span style="COLOR: #000000"> (</span>
								<span style="COLOR: #000000">!</span>
								<span style="COLOR: #000000">CreateEx(…)) </span>
								<span id="Codehighlighter1_53_63_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">
										<img src="http://www.cppblog.com/images/dot.gif" />
								</span>
						</font>
						<span id="Codehighlighter1_53_63_Open_Text">
								<font size="2">
										<span style="COLOR: #000000">{<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />        </span>
										<span style="COLOR: #008000">//</span>
										<span style="COLOR: #008000"> …</span>
								</font>
								<span style="COLOR: #008000">
										<br />
										<font size="2">
												<img src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />
										</font>
								</span>
								<font size="2">
										<span style="COLOR: #000000">    }</span>
								</font>
						</span>
						<span style="COLOR: #000000">
								<br />
								<font size="2">
										<img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    </font>
						</span>
						<font size="2">
								<span style="COLOR: #008000">//</span>
								<span style="COLOR: #008000"> …</span>
						</font>
						<span style="COLOR: #008000">
								<br />
								<font size="2">
										<img src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />
								</font>
						</span>
						<font size="2">
								<span style="COLOR: #000000">}</span>
						</font>
				</span>
				<span style="COLOR: #000000">
						<br />
						<font size="2">
								<img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />
								<br />
								<img id="Codehighlighter1_97_173_Open_Image" onclick="this.style.display='none'; Codehighlighter1_97_173_Open_Text.style.display='none'; Codehighlighter1_97_173_Closed_Image.style.display='inline'; Codehighlighter1_97_173_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" />
								<img id="Codehighlighter1_97_173_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_97_173_Closed_Text.style.display='none'; Codehighlighter1_97_173_Open_Image.style.display='inline'; Codehighlighter1_97_173_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align="top" />BOOL CWnd::CreateEx(…) </font>
				</span>
				<font size="2">
						<span id="Codehighlighter1_97_173_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">
								<img src="http://www.cppblog.com/images/dot.gif" />
						</span>
				</font>
				<span id="Codehighlighter1_97_173_Open_Text">
						<font size="2">
								<span style="COLOR: #000000">{<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    </span>
								<span style="COLOR: #008000">//</span>
								<span style="COLOR: #008000"> …</span>
						</font>
						<span style="COLOR: #008000">
								<br />
								<font size="2">
										<img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />
								</font>
						</span>
						<font size="2">
								<span style="COLOR: #000000">    AfxHookWindowCreate(</span>
								<span style="COLOR: #0000ff">this</span>
						</font>
						<font size="2">
								<span style="COLOR: #000000">);<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    HWND hWnd </span>
								<span style="COLOR: #000000">=</span>
						</font>
						<font size="2">
								<span style="COLOR: #000000"> ::CreateWindowEx(…);<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    </span>
								<span style="COLOR: #008000">//</span>
								<span style="COLOR: #008000"> …</span>
						</font>
						<span style="COLOR: #008000">
								<br />
								<font size="2">
										<img src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />
								</font>
						</span>
						<font size="2">
								<span style="COLOR: #000000">}</span>
						</font>
				</span>
				<span style="COLOR: #000000">
						<br />
						<font size="2">
								<img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />
								<br />
								<img id="Codehighlighter1_220_445_Open_Image" onclick="this.style.display='none'; Codehighlighter1_220_445_Open_Text.style.display='none'; Codehighlighter1_220_445_Closed_Image.style.display='inline'; Codehighlighter1_220_445_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" />
								<img id="Codehighlighter1_220_445_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_220_445_Closed_Text.style.display='none'; Codehighlighter1_220_445_Open_Image.style.display='inline'; Codehighlighter1_220_445_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align="top" />
						</font>
				</span>
				<font size="2">
						<span style="COLOR: #0000ff">void</span>
						<span style="COLOR: #000000"> AFXAPI AfxHookWindowCreate(CWnd</span>
						<span style="COLOR: #000000">*</span>
						<span style="COLOR: #000000"> pWnd) </span>
						<span id="Codehighlighter1_220_445_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">
								<img src="http://www.cppblog.com/images/dot.gif" />
						</span>
				</font>
				<span id="Codehighlighter1_220_445_Open_Text">
						<font size="2">
								<span style="COLOR: #000000">{<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    </span>
								<span style="COLOR: #008000">//</span>
								<span style="COLOR: #008000"> …</span>
						</font>
						<span style="COLOR: #008000">
								<br />
								<font size="2">
										<img id="Codehighlighter1_276_403_Open_Image" onclick="this.style.display='none'; Codehighlighter1_276_403_Open_Text.style.display='none'; Codehighlighter1_276_403_Closed_Image.style.display='inline'; Codehighlighter1_276_403_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" />
										<img id="Codehighlighter1_276_403_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_276_403_Closed_Text.style.display='none'; Codehighlighter1_276_403_Open_Image.style.display='inline'; Codehighlighter1_276_403_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />
								</font>
						</span>
						<font size="2">
								<span style="COLOR: #000000">    </span>
								<span style="COLOR: #0000ff">if</span>
								<span style="COLOR: #000000"> (pThreadState</span>
								<span style="COLOR: #000000">-&gt;</span>
								<span style="COLOR: #000000">m_hHookOldCbtFilter </span>
								<span style="COLOR: #000000">==</span>
								<span style="COLOR: #000000"> NULL) </span>
								<span id="Codehighlighter1_276_403_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">
										<img src="http://www.cppblog.com/images/dot.gif" />
								</span>
						</font>
						<span id="Codehighlighter1_276_403_Open_Text">
								<font size="2">
										<span style="COLOR: #000000">{<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />        pThreadState</span>
										<span style="COLOR: #000000">-&gt;</span>
										<span style="COLOR: #000000">m_hHookOldCbtFilter </span>
										<span style="COLOR: #000000">=</span>
								</font>
								<font size="2">
										<span style="COLOR: #000000"> ::SetWindowsHookEx(WH_CBT,<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />        _AfxCbtFilterHook, NULL, ::GetCurrentThreadId());<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />        </span>
										<span style="COLOR: #008000">//</span>
										<span style="COLOR: #008000"> …</span>
								</font>
								<span style="COLOR: #008000">
										<br />
										<font size="2">
												<img src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />
										</font>
								</span>
								<font size="2">
										<span style="COLOR: #000000">    }</span>
								</font>
						</span>
						<span style="COLOR: #000000">
								<br />
								<font size="2">
										<img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    </font>
						</span>
						<font size="2">
								<span style="COLOR: #008000">//</span>
								<span style="COLOR: #008000"> …</span>
						</font>
						<span style="COLOR: #008000">
								<br />
								<font size="2">
										<img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />
								</font>
						</span>
						<font size="2">
								<span style="COLOR: #000000">    pThreadState</span>
								<span style="COLOR: #000000">-&gt;</span>
								<span style="COLOR: #000000">m_pWndInit </span>
								<span style="COLOR: #000000">=</span>
						</font>
						<font size="2">
								<span style="COLOR: #000000"> pWnd;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span>
						</font>
				</span>
		</div>
		<p>
				<font size="2">这样，通过AfxHookWindowCreate，在当前线程中安装了一个钩子，用来拦截和窗口相关的事件，每当：<br /><br />1. 另一个窗口成为active；<br />2. 产生或摧毁一个窗口<br />3. Minimize或maximize一个窗口；<br />4. 移动或缩放一个窗口；<br />5. 完成一个来自系统菜单的命令；<br />6. 从系统队列中取出一个消息；<br /><br />时，都会先调用_AfxCbtFilterHook，接下来看看钩子函数作了什么：</font>
		</p>
		<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee">
				<font size="2">
						<img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />
				</font>
				<font size="2">
						<span style="COLOR: #000000">LRESULT CALLBACK<br /><img id="Codehighlighter1_75_214_Open_Image" onclick="this.style.display='none'; Codehighlighter1_75_214_Open_Text.style.display='none'; Codehighlighter1_75_214_Closed_Image.style.display='inline'; Codehighlighter1_75_214_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_75_214_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_75_214_Closed_Text.style.display='none'; Codehighlighter1_75_214_Open_Image.style.display='inline'; Codehighlighter1_75_214_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align="top" />_AfxCbtFilterHook(</span>
						<span style="COLOR: #0000ff">int</span>
						<span style="COLOR: #000000"> code, WPARAM wParam, LPARAM lParam) </span>
						<span id="Codehighlighter1_75_214_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">
								<img src="http://www.cppblog.com/images/dot.gif" />
						</span>
				</font>
				<span id="Codehighlighter1_75_214_Open_Text">
						<font size="2">
								<span style="COLOR: #000000">{<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    </span>
								<span style="COLOR: #008000">//</span>
								<span style="COLOR: #008000"> …</span>
						</font>
						<span style="COLOR: #008000">
								<br />
								<font size="2">
										<img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />
								</font>
						</span>
						<font size="2">
								<span style="COLOR: #000000">    WNDPROC afxWndProc </span>
								<span style="COLOR: #000000">=</span>
						</font>
						<font size="2">
								<span style="COLOR: #000000"> AfxGetAfxWndProc();<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    oldWndProc </span>
								<span style="COLOR: #000000">=</span>
						</font>
						<font size="2">
								<span style="COLOR: #000000"> (WNDPROC)SetWindowLongPtr(hWnd, GWLP_WNDPROC,(DWORD_PTR)afxWndProc);<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    </span>
								<span style="COLOR: #008000">//</span>
								<span style="COLOR: #008000"> …</span>
						</font>
						<span style="COLOR: #008000">
								<br />
								<font size="2">
										<img src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />
								</font>
						</span>
						<font size="2">
								<span style="COLOR: #000000">}</span>
						</font>
				</span>
				<span style="COLOR: #000000">
						<br />
						<font size="2">
								<img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />
								<br />
								<img id="Codehighlighter1_251_280_Open_Image" onclick="this.style.display='none'; Codehighlighter1_251_280_Open_Text.style.display='none'; Codehighlighter1_251_280_Closed_Image.style.display='inline'; Codehighlighter1_251_280_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" />
								<img id="Codehighlighter1_251_280_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_251_280_Closed_Text.style.display='none'; Codehighlighter1_251_280_Open_Image.style.display='inline'; Codehighlighter1_251_280_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align="top" />WNDPROC AFXAPI AfxGetAfxWndProc() </font>
				</span>
				<font size="2">
						<span id="Codehighlighter1_251_280_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">
								<img src="http://www.cppblog.com/images/dot.gif" />
						</span>
				</font>
				<span id="Codehighlighter1_251_280_Open_Text">
						<font size="2">
								<span style="COLOR: #000000">{<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    </span>
								<span style="COLOR: #008000">//</span>
								<span style="COLOR: #008000"> …</span>
						</font>
						<span style="COLOR: #008000">
								<br />
								<font size="2">
										<img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />
								</font>
						</span>
						<font size="2">
								<span style="COLOR: #000000">    </span>
								<span style="COLOR: #0000ff">return</span>
								<span style="COLOR: #000000"> </span>
								<span style="COLOR: #000000">&amp;</span>
						</font>
						<font size="2">
								<span style="COLOR: #000000">AfxWndProc;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span>
						</font>
				</span>
		</div>
		<p>
				<font size="2">这样，_AfxCbtFilterHook的工作总结起来就是通过窗口子类化，把新建的窗口的窗口过程设置成AfxWndProc。<br />到这里，我们终于找到了窗口过程。<br /><br /><strong>结论</strong><br />CFrameWnd::Create创建窗口调用CWnd::CreateEx<br />CWnd::CreateEx调用AfxHookWindowCreate准备为窗口设置钩子<br />AfxHookWindowCreate调用::SetWindowHookEx为窗口设置了一个WH_CBT类型的钩子来过滤消息，并把过滤函数设置成_AfxCbtFilterHook<br />_AfxCbtFilterHook通过窗口子类化设置窗口的窗口过程为AfxWndProc<br />这样，通过::DispatchMessage发送给窗口的消息就会源源不断地送到AfxWndProc中来，可以想到，AfxWndProc利用MFC的消息映射表，分门别类的对消息进行分流。<br /><br />（待续……）</font>
				<br />
		</p>
		<br />
<img src ="http://www.cppblog.com/nacci/aggbug/7365.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/nacci/" target="_blank">nacci</a> 2006-05-18 17:29 <a href="http://www.cppblog.com/nacci/archive/2006/05/18/7365.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>MFC漫谈（三）——消息映射</title><link>http://www.cppblog.com/nacci/archive/2006/05/18/7363.html</link><dc:creator>nacci</dc:creator><author>nacci</author><pubDate>Thu, 18 May 2006 08:31:00 GMT</pubDate><guid>http://www.cppblog.com/nacci/archive/2006/05/18/7363.html</guid><wfw:comment>http://www.cppblog.com/nacci/comments/7363.html</wfw:comment><comments>http://www.cppblog.com/nacci/archive/2006/05/18/7363.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.cppblog.com/nacci/comments/commentRss/7363.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/nacci/services/trackbacks/7363.html</trackback:ping><description><![CDATA[
		<p>
				<font size="2">MFC中的消息循环呢？我们熟悉的switch……case……到哪里去了？<br /></font>
		</p>
		<font size="2">
				<hr />
				<br />在MFC中，消息的循环并不是用switch……case……实现的，它依赖于一张由程序自身定义的消息网。<br /><br />首先，MFC用一个名为AFX_MSGMAP_ENTRY结构来对消息的信息进行封装： </font>
		<p>
		</p>
		<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee">
				<font size="2">
						<img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />
						<span style="COLOR: #0000ff">struct</span>
				</font>
				<font size="2">
						<span style="COLOR: #000000"> AFX_MSGMAP_ENTRY<br /><img id="Codehighlighter1_24_379_Open_Image" onclick="this.style.display='none'; Codehighlighter1_24_379_Open_Text.style.display='none'; Codehighlighter1_24_379_Closed_Image.style.display='inline'; Codehighlighter1_24_379_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_24_379_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_24_379_Closed_Text.style.display='none'; Codehighlighter1_24_379_Open_Image.style.display='inline'; Codehighlighter1_24_379_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align="top" /></span>
						<span id="Codehighlighter1_24_379_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">
								<img src="http://www.cppblog.com/images/dot.gif" />
						</span>
				</font>
				<span id="Codehighlighter1_24_379_Open_Text">
						<font size="2">
								<span style="COLOR: #000000">{<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />　　UINT nMessage;   </span>
								<span style="COLOR: #008000">//</span>
								<span style="COLOR: #008000"> windows message</span>
						</font>
						<span style="COLOR: #008000">
								<br />
								<font size="2">
										<img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />
								</font>
						</span>
						<font size="2">
								<span style="COLOR: #000000">　　UINT nCode;      　</span>
								<span style="COLOR: #008000">//</span>
								<span style="COLOR: #008000"> control code or WM_NOTIFY code</span>
						</font>
						<span style="COLOR: #008000">
								<br />
								<font size="2">
										<img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />
								</font>
						</span>
						<font size="2">
								<span style="COLOR: #000000">　　UINT nID;        　　</span>
								<span style="COLOR: #008000">//</span>
								<span style="COLOR: #008000"> control ID (or 0 for windows messages)</span>
						</font>
						<span style="COLOR: #008000">
								<br />
								<font size="2">
										<img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />
								</font>
						</span>
						<font size="2">
								<span style="COLOR: #000000">　　UINT nLastID;    　</span>
								<span style="COLOR: #008000">//</span>
								<span style="COLOR: #008000"> used for entries specifying a range of control id's</span>
						</font>
						<span style="COLOR: #008000">
								<br />
								<font size="2">
										<img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />
								</font>
						</span>
						<font size="2">
								<span style="COLOR: #000000">　　UINT_PTR nSig;   　</span>
								<span style="COLOR: #008000">//</span>
								<span style="COLOR: #008000"> signature type (action) or pointer to message #</span>
						</font>
						<span style="COLOR: #008000">
								<br />
								<font size="2">
										<img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />
								</font>
						</span>
						<font size="2">
								<span style="COLOR: #000000">　　AFX_PMSG pfn;    </span>
								<span style="COLOR: #008000">//</span>
								<span style="COLOR: #008000"> routine to call (or special value)</span>
						</font>
						<span style="COLOR: #008000">
								<br />
								<font size="2">
										<img src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />
								</font>
						</span>
						<span style="COLOR: #000000">
								<font size="2">}</font>
						</span>
				</span>
				<span style="COLOR: #000000">
						<font size="2">;</font>
				</span>
		</div>
		<p>
				<font size="2">其中　typedef void (AFX_MSG_CALL CCmdTarget::*AFX_PMSG)(void);<br /><br />之后，通过一个链表，把这些描述消息的结构组织起来，构成消息映射表的结构是AFX_MSGMAP</font>
		</p>
		<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee">
				<font size="2">
						<img id="Codehighlighter1_18_87_Open_Image" onclick="this.style.display='none'; Codehighlighter1_18_87_Open_Text.style.display='none'; Codehighlighter1_18_87_Closed_Image.style.display='inline'; Codehighlighter1_18_87_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" />
						<img id="Codehighlighter1_18_87_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_18_87_Closed_Text.style.display='none'; Codehighlighter1_18_87_Open_Image.style.display='inline'; Codehighlighter1_18_87_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align="top" />
						<span style="COLOR: #0000ff">struct</span>
						<span style="COLOR: #000000"> AFX_MSGMAP　</span>
						<span id="Codehighlighter1_18_87_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">
								<img src="http://www.cppblog.com/images/dot.gif" />
						</span>
				</font>
				<span id="Codehighlighter1_18_87_Open_Text">
						<font size="2">
								<span style="COLOR: #000000">{<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />　　</span>
								<span style="COLOR: #0000ff">const</span>
								<span style="COLOR: #000000"> AFX_MSGMAP</span>
								<span style="COLOR: #000000">*</span>
						</font>
						<font size="2">
								<span style="COLOR: #000000"> pBaseMap;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />　　</span>
								<span style="COLOR: #0000ff">const</span>
								<span style="COLOR: #000000"> AFX_MSGMAP_ENTRY</span>
								<span style="COLOR: #000000">*</span>
						</font>
						<span style="COLOR: #000000">
								<font size="2"> lpEntries;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</font>
						</span>
				</span>
				<span style="COLOR: #000000">
						<font size="2">;</font>
				</span>
		</div>
		<p>
				<font size="2">这样一个AFX_MSGMAP对象就成了构建消息映射表的关键人物，它一只手拉着基类的AFX_MSGMAP对象，另一只手拉着类本身的消息映射表，这样只要正确地在每一个类中都安插一个AFX_MSGMAP对象，那么整个消息映射表就建立起来了。那么，何为正确呢？含义有2：一是正确的设置pBaseMap，令它指向基类，二是正确的建立类自身的消息映射表。这两个工作是由4个宏完成的，<br /><br />它们是：DECLARE_MEMSSAGE_MAP() / BEGIN_MESSAGE_MAP() / ON_COMMAND()（注：ON_COMMAND宏只是为了处理命令消息，对于其它的消息还有对应的宏，但是原理是相同的） / END_MESSAGE_MAP()。<br />让我们一个个的看看：</font>
		</p>
		<p>
				<font size="2">
				</font>
		</p>
		<p>
				<font size="2">
				</font>
		</p>
		<p>
				<font size="2">
				</font>
		</p>
		<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee">
				<font size="2">
						<img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />
						<span style="COLOR: #0000ff">#define</span>
						<span style="COLOR: #000000"> DECLARE_MESSAGE_MAP() \</span>
				</font>
				<span style="COLOR: #000000">
						<br />
						<font size="2">
								<img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />
						</font>
				</span>
				<font size="2">
						<span style="COLOR: #0000ff">private</span>
				</font>
				<font size="2">
						<span style="COLOR: #000000">: \<br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />　　</span>
						<span style="COLOR: #0000ff">static</span>
						<span style="COLOR: #000000"> </span>
						<span style="COLOR: #0000ff">const</span>
				</font>
				<font size="2">
						<span style="COLOR: #000000"> AFX_MSGMAP_ENTRY _messageEntries[]; \<br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /></span>
						<span style="COLOR: #0000ff">protected</span>
				</font>
				<font size="2">
						<span style="COLOR: #000000">: \<br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />　　</span>
						<span style="COLOR: #0000ff">static</span>
						<span style="COLOR: #000000"> </span>
						<span style="COLOR: #0000ff">const</span>
				</font>
				<font size="2">
						<span style="COLOR: #000000"> AFX_MSGMAP messageMap; \<br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />　　</span>
						<span style="COLOR: #0000ff">virtual</span>
						<span style="COLOR: #000000"> </span>
						<span style="COLOR: #0000ff">const</span>
						<span style="COLOR: #000000"> AFX_MSGMAP</span>
						<span style="COLOR: #000000">*</span>
						<span style="COLOR: #000000"> GetMessageMap() </span>
						<span style="COLOR: #0000ff">const</span>
						<span style="COLOR: #000000">; \</span>
				</font>
		</div>
		<p>
				<font size="2">这个宏的作用有3：<br /> 1. 在类中插入一个静态成员_messageEntries，这是用来存放类要处理的消息的数组（即类本身的消息映射表）<br /> 2.  另一个静态成员massageMap用来指向基类的消息映射表<br /> 3. 安插一个虚函数，其内容有待实现</font>
		</p>
		<p>
				<font size="2">接下来，_messageEntries的初始化，messageMap的正确指向，GetMessageMap函数的实现这些工作还都没做，那正是后三个宏的责任，它们要顺序使用，方能工作正常。 </font>
		</p>
		<p>
				<font size="2">
				</font>
		</p>
		<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee">
				<font size="2">
						<img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />
						<span style="COLOR: #0000ff">#define</span>
						<span style="COLOR: #000000"> BEGIN_MESSAGE_MAP(theClass, baseClass) \</span>
				</font>
				<span style="COLOR: #000000">
						<br />
						<font size="2">
								<img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />  </font>
				</span>
				<font size="2">
						<span style="COLOR: #0000ff">const</span>
						<span style="COLOR: #000000"> AFX_MSGMAP</span>
						<span style="COLOR: #000000">*</span>
						<span style="COLOR: #000000"> theClass::GetMessageMap() </span>
						<span style="COLOR: #0000ff">const</span>
				</font>
				<font size="2">
						<span style="COLOR: #000000"> \<br /><img id="Codehighlighter1_107_139_Open_Image" onclick="this.style.display='none'; Codehighlighter1_107_139_Open_Text.style.display='none'; Codehighlighter1_107_139_Closed_Image.style.display='inline'; Codehighlighter1_107_139_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_107_139_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_107_139_Closed_Text.style.display='none'; Codehighlighter1_107_139_Open_Image.style.display='inline'; Codehighlighter1_107_139_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align="top" />  </span>
						<span id="Codehighlighter1_107_139_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">
								<img src="http://www.cppblog.com/images/dot.gif" />
						</span>
						<span id="Codehighlighter1_107_139_Open_Text">
								<span style="COLOR: #000000">{ </span>
								<span style="COLOR: #0000ff">return</span>
								<span style="COLOR: #000000"> </span>
								<span style="COLOR: #000000">&amp;</span>
								<span style="COLOR: #000000">theClass::messageMap; }</span>
						</span>
				</font>
				<font size="2">
						<span style="COLOR: #000000"> \<br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />  AFX_COMDAT </span>
						<span style="COLOR: #0000ff">const</span>
						<span style="COLOR: #000000"> AFX_MSGMAP theClass::messageMap </span>
						<span style="COLOR: #000000">=</span>
				</font>
				<font size="2">
						<span style="COLOR: #000000"> \<br /><img id="Codehighlighter1_202_258_Open_Image" onclick="this.style.display='none'; Codehighlighter1_202_258_Open_Text.style.display='none'; Codehighlighter1_202_258_Closed_Image.style.display='inline'; Codehighlighter1_202_258_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_202_258_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_202_258_Closed_Text.style.display='none'; Codehighlighter1_202_258_Open_Image.style.display='inline'; Codehighlighter1_202_258_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align="top" />  </span>
						<span id="Codehighlighter1_202_258_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">
								<img src="http://www.cppblog.com/images/dot.gif" />
						</span>
						<span id="Codehighlighter1_202_258_Open_Text">
								<span style="COLOR: #000000">{ </span>
								<span style="COLOR: #000000">&amp;</span>
								<span style="COLOR: #000000">baseClass::messageMap, </span>
								<span style="COLOR: #000000">&amp;</span>
								<span style="COLOR: #000000">theClass::_messageEntries[</span>
								<span style="COLOR: #000000">0</span>
								<span style="COLOR: #000000">] }</span>
						</span>
				</font>
				<font size="2">
						<span style="COLOR: #000000">; \<br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />  AFX_COMDAT </span>
						<span style="COLOR: #0000ff">const</span>
						<span style="COLOR: #000000"> AFX_MSGMAP_ENTRY theClass::_messageEntries[] </span>
						<span style="COLOR: #000000">=</span>
				</font>
				<font size="2">
						<span style="COLOR: #000000"> \<br /><img id="Codehighlighter1_334_338_Open_Image" onclick="this.style.display='none'; Codehighlighter1_334_338_Open_Text.style.display='none'; Codehighlighter1_334_338_Closed_Image.style.display='inline'; Codehighlighter1_334_338_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_334_338_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_334_338_Closed_Text.style.display='none'; Codehighlighter1_334_338_Open_Image.style.display='inline'; Codehighlighter1_334_338_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align="top" /> </span>
						<span id="Codehighlighter1_334_338_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">
								<img src="http://www.cppblog.com/images/dot.gif" />
						</span>
						<span id="Codehighlighter1_334_338_Open_Text">
								<span style="COLOR: #000000">{ \</span>
						</span>
				</font>
		</div>
		<p>
				<font size="2">这个宏的作用有3：<br />1. 定义了安插在类中的虚函数GetMessageMap()，只是简单的返回messageMap对象的地址<br />2. 初始化messageMap，把派生类和基类联系起来构成一个大的消息映射表<br />3. 为类本身的消息映射表的初始化做语法准备</font>
		</p>
		<p>
				<font size="2">ON_COMMAND这个宏的作用就是向_messageEntries数组中添加类本身要处理的命令消息，其实在MFC中还有很多更方便的宏可以向类中添加消息，例如OM_WM_PAINT等，这里，我们主要讨论ON_COMMAND，毕竟原理都是相同的。<br /></font>
		</p>
		<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee">
				<font size="2">
						<img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />
						<span style="COLOR: #0000ff">#define</span>
						<span style="COLOR: #000000"> ON_COMMAND(id, memberFxn) \</span>
				</font>
				<span style="COLOR: #000000">
						<br />
						<font size="2">
								<img id="Codehighlighter1_37_135_Open_Image" onclick="this.style.display='none'; Codehighlighter1_37_135_Open_Text.style.display='none'; Codehighlighter1_37_135_Closed_Image.style.display='inline'; Codehighlighter1_37_135_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" />
								<img id="Codehighlighter1_37_135_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_37_135_Closed_Text.style.display='none'; Codehighlighter1_37_135_Open_Image.style.display='inline'; Codehighlighter1_37_135_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align="top" />
						</font>
				</span>
				<span id="Codehighlighter1_37_135_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">
						<font size="2">
								<img src="http://www.cppblog.com/images/dot.gif" />
						</font>
				</span>
				<font size="2">
						<span id="Codehighlighter1_37_135_Open_Text">
								<span style="COLOR: #000000">{ WM_COMMAND, CN_COMMAND, (WORD)id, (WORD)id, AfxSigCmd_v, \<br /><img src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />  static_cast</span>
								<span style="COLOR: #000000">&lt;</span>
								<span style="COLOR: #000000">AFX_PMSG</span>
								<span style="COLOR: #000000">&gt;</span>
								<span style="COLOR: #000000"> (memberFxn) }</span>
						</span>
						<span style="COLOR: #000000">,</span>
				</font>
		</div>
		<p>
				<font size="2">无非是对AFX_MSG_ENTRY结构的初始化，这样在类中为每一个想要处理的消息都是用一个ON_COMMAND宏，就自动的初始化了类本身的消息映射表。</font>
		</p>
		<p>
				<font size="2">最后，当全部的信息添加完毕后，使用END_MESSAGE_MAP()宏通知MFC一个类消息映射表结束了。<br /></font>
		</p>
		<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee">
				<font size="2">
						<img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />
						<span style="COLOR: #0000ff">#define</span>
						<span style="COLOR: #000000"> END_MESSAGE_MAP() \</span>
				</font>
				<span style="COLOR: #000000">
						<br />
						<font size="2">
								<img id="Codehighlighter1_31_68_Open_Image" onclick="this.style.display='none'; Codehighlighter1_31_68_Open_Text.style.display='none'; Codehighlighter1_31_68_Closed_Image.style.display='inline'; Codehighlighter1_31_68_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" />
								<img id="Codehighlighter1_31_68_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_31_68_Closed_Text.style.display='none'; Codehighlighter1_31_68_Open_Image.style.display='inline'; Codehighlighter1_31_68_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align="top" />  </font>
				</span>
				<font size="2">
						<span id="Codehighlighter1_31_68_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">
								<img src="http://www.cppblog.com/images/dot.gif" />
						</span>
						<span id="Codehighlighter1_31_68_Open_Text">
								<span style="COLOR: #000000">{</span>
								<span style="COLOR: #000000">0</span>
								<span style="COLOR: #000000">, </span>
								<span style="COLOR: #000000">0</span>
								<span style="COLOR: #000000">, </span>
								<span style="COLOR: #000000">0</span>
								<span style="COLOR: #000000">, </span>
								<span style="COLOR: #000000">0</span>
								<span style="COLOR: #000000">, AfxSig_end, (AFX_PMSG)</span>
								<span style="COLOR: #000000">0</span>
								<span style="COLOR: #000000"> }</span>
						</span>
				</font>
				<font size="2">
						<span style="COLOR: #000000"> \<br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /> }; \</span>
				</font>
		</div>
		<p>
				<font size="2">实现手法单纯得很，无非是一个全0的AFX_MESSAGE_MAP对象。<br /><br /></font>
				<font size="2">
						<strong>
								<font size="3">结论<br /></font>
						</strong>想要让你的类处理某个消息，使用下面的组合：</font>
		</p>
		<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee">
				<font size="2">
						<img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />
						<span style="COLOR: #000000">BEGIN_MESSAGE_MAP(theClass, the </span>
						<span style="COLOR: #0000ff">base</span>
				</font>
				<font size="2">
						<span style="COLOR: #000000"> Class)<br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /></span>
						<span style="COLOR: #008000">//</span>
						<span style="COLOR: #008000">消息处理宏</span>
				</font>
				<span style="COLOR: #008000">
						<br />
						<font size="2">
								<img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />
						</font>
				</span>
				<font size="2">
						<span style="COLOR: #000000">END_MESSAGE_MAP()</span>
				</font>
		</div>
		<br />
		<font size="2">（待续……）</font>
<img src ="http://www.cppblog.com/nacci/aggbug/7363.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/nacci/" target="_blank">nacci</a> 2006-05-18 16:31 <a href="http://www.cppblog.com/nacci/archive/2006/05/18/7363.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>MFC漫谈（二）——对象的动态创建</title><link>http://www.cppblog.com/nacci/archive/2006/05/18/7355.html</link><dc:creator>nacci</dc:creator><author>nacci</author><pubDate>Thu, 18 May 2006 08:07:00 GMT</pubDate><guid>http://www.cppblog.com/nacci/archive/2006/05/18/7355.html</guid><wfw:comment>http://www.cppblog.com/nacci/comments/7355.html</wfw:comment><comments>http://www.cppblog.com/nacci/archive/2006/05/18/7355.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/nacci/comments/commentRss/7355.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/nacci/services/trackbacks/7355.html</trackback:ping><description><![CDATA[
		<p>
				<font size="2">接上次RTTI的话题。<br /><hr /><br />能够在运行时发现一个对象的类型，就可以在运行时动态的创建一个对象。在一个类库中，拥有统一的对象创建方式是非常重要的。<br /><p></p><p>在MFC中，对象的动态创建要依赖于RTTI所建立起来的类别型录，和动态创建有关的CRuntimeClass成员有两个：</p><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /><span style="COLOR: #000000">CObject</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000"> (PASCAL</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000"> m_pfnCreateObject)(); </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> 指向用于创建对象的函数</span><span style="COLOR: #008000"><br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #000000">CObject</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000"> CreateObject(); </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> 利用m_pfnCreateObject创建对象</span></div><p>利用RTTI建立的类别型录，DECLARE_DYNCREATE / IMPLEMENT_DYNCREATE继续为类添加了动态创建的功能。</p><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /><span style="COLOR: #0000ff">#define</span><span style="COLOR: #000000"> DECLARE_DYNCREATE (class_name) \</span><span style="COLOR: #000000"><br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />　　　　DECLARE_DYNAMIC (class_name) \ <br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />　　　　</span><span style="COLOR: #0000ff">static</span><span style="COLOR: #000000"> CObject</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000"> PASCAL CreateObject();</span></div><p>这个宏同样用在类声明中，它不但为类添加了class##class_name对象和GetRuntimeClass()，还为类加入了一个静态函数CreateObject,用来进行对象的动态创建。同样IMPLEMENT_DYNCREATE用来对上面添加的内容作定义和初始化工作。</p><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /><span style="COLOR: #0000ff">#define</span><span style="COLOR: #000000"> IMPLEMENT_DYNCREATE (class_name, base_class_name) \</span><span style="COLOR: #000000"><br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />　　　　CObject</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000"> PASCAL class_name::CreateObject() \<br /><img id="Codehighlighter1_115_140_Open_Image" onclick="this.style.display='none'; Codehighlighter1_115_140_Open_Text.style.display='none'; Codehighlighter1_115_140_Closed_Image.style.display='inline'; Codehighlighter1_115_140_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_115_140_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_115_140_Closed_Text.style.display='none'; Codehighlighter1_115_140_Open_Image.style.display='inline'; Codehighlighter1_115_140_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align="top" />　　　　</span><span id="Codehighlighter1_115_140_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/images/dot.gif" /></span><span id="Codehighlighter1_115_140_Open_Text"><span style="COLOR: #000000">{ </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000"> class_name; }</span></span><span style="COLOR: #000000"> \<br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />　　　　IMPLEMENT_RUNTIMECLASS (class_name, base_class_name, </span><span style="COLOR: #000000">0xFFFF</span><span style="COLOR: #000000">, \<br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />　　　　class_name::CreateObject, NULL)</span></div><p>和IMPLEMENT_DYNAMIC不同的是，这里的IMPLEMENT_RUNTIMECLASS中的第4个参数并不为NULL，而是class_name::CreateObject，这样就指定了用于创建对象的函数，至于其它的内容，与RTTI没有什么不同。<br /><br />于是，整个对象的动态创建过程就变得非常简单了，只要我们找到某个特定类的CRuntimeClass对象，利用class##class_name.CreateObject()就可以了。</p><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /><span style="COLOR: #000000">CObject</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000"> CRuntimeClass::CreateObject()<br /><img id="Codehighlighter1_39_122_Open_Image" onclick="this.style.display='none'; Codehighlighter1_39_122_Open_Text.style.display='none'; Codehighlighter1_39_122_Closed_Image.style.display='inline'; Codehighlighter1_39_122_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_39_122_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_39_122_Closed_Text.style.display='none'; Codehighlighter1_39_122_Open_Image.style.display='inline'; Codehighlighter1_39_122_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align="top" /></span><span id="Codehighlighter1_39_122_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/images/dot.gif" /></span><span id="Codehighlighter1_39_122_Open_Text"><span style="COLOR: #000000">{<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />　　CObject</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000"> pObject </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> NULL;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />　　pObject </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> (</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">m_pfnCreateObject)();<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />　　</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> pObject;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span></span></div><p><font size="3"><strong>结论<br /></strong></font>想让你的类在MFC中支持动态创建，<br />1. 在类声明中使用DECLARE_DYNAMIC<br />2. 在类定义文件中使用IMPLEMENT_DYNAMIC，此时<br />    class##class_name.m_pfnCreateObject = class_name::CreateObject;　<br />    CRuntimeClass::CreateObject利用m_pfnCreateObject就可以进行对象的动态创建了<br />                                                                                                                                                （待续……）<br /></p></font>
		</p>
		<p>
		</p>
<img src ="http://www.cppblog.com/nacci/aggbug/7355.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/nacci/" target="_blank">nacci</a> 2006-05-18 16:07 <a href="http://www.cppblog.com/nacci/archive/2006/05/18/7355.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>MFC漫谈（一）——RTTI</title><link>http://www.cppblog.com/nacci/archive/2006/05/18/7350.html</link><dc:creator>nacci</dc:creator><author>nacci</author><pubDate>Thu, 18 May 2006 06:53:00 GMT</pubDate><guid>http://www.cppblog.com/nacci/archive/2006/05/18/7350.html</guid><wfw:comment>http://www.cppblog.com/nacci/comments/7350.html</wfw:comment><comments>http://www.cppblog.com/nacci/archive/2006/05/18/7350.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/nacci/comments/commentRss/7350.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/nacci/services/trackbacks/7350.html</trackback:ping><description><![CDATA[
		<span style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">所有的这一系列的东西都来源于前天晚上的一个电话，内容大概是说：</span>
		<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Times New Roman'; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-fareast-font-family: 宋体">“</span>
		<span style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">你能教会我一个让我对</span>
		<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Times New Roman'; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-fareast-font-family: 宋体">MFC</span>
		<span style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">有点感觉的</span>
		<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Times New Roman'; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-fareast-font-family: 宋体">Hello World</span>
		<span style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">吗？我渴望一个像用</span>
		<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Times New Roman'; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-fareast-font-family: 宋体">C</span>
		<span style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">写的</span>
		<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Times New Roman'; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-fareast-font-family: 宋体">Win32 Hello World</span>
		<span style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">一样直观的例子。</span>
		<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Times New Roman'; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-fareast-font-family: 宋体">”</span>
		<span style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">想想这曾经是我学习</span>
		<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Times New Roman'; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-fareast-font-family: 宋体">MFC</span>
		<span style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">的时候也想到过的问题。我是一个喜欢刨根问底的人，喜欢把事情搞明白，于是曾经很长的一段时间里，我都困惑在纷繁杂乱的代码里。现在回想起来，侯捷老师的《</span>
		<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Times New Roman'; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-fareast-font-family: 宋体">Dessecting MFC</span>
		<span style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">》和</span>
		<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Times New Roman'; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-fareast-font-family: 宋体">Jeff Prosise</span>
		<span style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">的《</span>
		<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Times New Roman'; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-fareast-font-family: 宋体">Programming MFC</span>
		<span style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">》一起读来，估计能达到解惑的目的。当然，需要的是一点点耐心和对</span>
		<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Times New Roman'; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-fareast-font-family: 宋体">Win32</span>
		<span style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">程序的一点最基本的了解（貌似废话。。。）。于是那天晚上，</span>
		<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Times New Roman'; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-fareast-font-family: 宋体">QQ</span>
		<span style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">上和那个朋友聊了挺长一段时间，翻腾了一下</span>
		<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Times New Roman'; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-fareast-font-family: 宋体">MFC</span>
		<span style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">的源代码，就有了这一系列的东西，全当是故地重游了一番。言归正传吧。文章中所有的代码都提取自MFC 7.0<br /><hr /><br /><font face="Times New Roman">在MFC中，RTTI是依靠为彼此有继承关系的类建立一个记录其类型的链表来实现的，和RTTI有关的CRuntimeClass成员有4个：<br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /><span style="COLOR: #000000">LPCSTR m_lpszClassName;    </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> 用于记录类名<br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> 用于指向基类的CRuntimeClass结构</span><span style="COLOR: #008000"><br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #000000">CRuntimeClass</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000"> m_pBaseClass;  <br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> 用于指向链表中前一个类的CRuntimeClass结构</span><span style="COLOR: #008000"><br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #000000">CRuntimeClass</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000"> m_pNextClass;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> 用于建立类别型录</span><span style="COLOR: #008000"><br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000"> AFX_CLASSINIT</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000"> m_pClassInit; </span></div><br />这样在这个类别型录中就有了许多条路径，每一条都是沿着m_pBaseClass一直可以找到某个类的最终基类。要把一个类加入到这个类别型录中要用到两个宏：<br /><span style="COLOR: #000000">DECLARE_DYNAMIC </span><span style="COLOR: #000000">/</span><span style="COLOR: #000000"> IMPLEMENT_DYNAMIC<br /></span>其中：<br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /><span style="COLOR: #0000ff">#define</span><span style="COLOR: #000000"> DECLARE_DYNAMIC (class_name) \</span><span style="COLOR: #000000"><br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">: \<br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />    </span><span style="COLOR: #0000ff">static</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000"> CRuntimeClass </span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">##class_name; \<br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />    </span><span style="COLOR: #0000ff">virtual</span><span style="COLOR: #000000"> CRuntimeClass</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000"> GetRuntimeClass() </span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000">; \</span></div><br />这个宏是用在类声明中的，其作用就是根据类的名字为该类添加两个public的成员，分别用于记录类的型别和获得对象class##class_name的地址，注意这里的class##class_name是个静态成员，这就为后面我们做类型的比较奠定了基础（继承于同一个基类的派生类对象包含共同的静态类成员）。在类中使用了DECLARE_DYNAMIC后，还要在.cpp的文件中使用IMPLEMENT_DYNAMIC宏，该宏的作用就是初始化class##class_name对象和定义GetRuntimeClass函数。<br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /><span style="COLOR: #0000ff">#define</span><span style="COLOR: #000000"> IMPLEMENT_DYNAMIC (class_name, base_class_name) \</span><span style="COLOR: #000000"><br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />    IMPLEMENT_RUNTIMECLASS (class_name, base_class_name, </span><span style="COLOR: #000000">0xFFFF</span><span style="COLOR: #000000">, NULL, NULL)</span></div><br />IMPLEMENT_DYNAMIC在使用的时候，要指定类和其基类的名字，之后利用IMPLEMENT_RUNTIMECLASS进行实质性的初始化活动。<br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /><span style="COLOR: #0000ff">#define</span><span style="COLOR: #000000"> IMPLEMENT_RUNTIMECLASS (class_name, base_class_name, wSchema, pfnNew, class_init) \</span><span style="COLOR: #000000"><br /><img id="Codehighlighter1_157_274_Open_Image" onclick="this.style.display='none'; Codehighlighter1_157_274_Open_Text.style.display='none'; Codehighlighter1_157_274_Closed_Image.style.display='inline'; Codehighlighter1_157_274_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_157_274_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_157_274_Closed_Text.style.display='none'; Codehighlighter1_157_274_Open_Image.style.display='inline'; Codehighlighter1_157_274_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align="top" />    AFX_COMDAT </span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000"> CRuntimeClass class_name::</span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">##class_name </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span id="Codehighlighter1_157_274_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/images/dot.gif" /></span><span id="Codehighlighter1_157_274_Open_Text"><span style="COLOR: #000000">{ \<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />        　　#class_name, </span><span style="COLOR: #0000ff">sizeof</span><span style="COLOR: #000000">(</span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> class_name), wSchema, pfnNew, \<br /><img src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />        　　RUNTIME_CLASS(base_class_name), NULL, class_init }</span></span><span style="COLOR: #000000">; \<br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />    CRuntimeClass</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000"> class_name::GetRuntimeClass() </span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000"> \<br /><img id="Codehighlighter1_337_374_Open_Image" onclick="this.style.display='none'; Codehighlighter1_337_374_Open_Text.style.display='none'; Codehighlighter1_337_374_Closed_Image.style.display='inline'; Codehighlighter1_337_374_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_337_374_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_337_374_Closed_Text.style.display='none'; Codehighlighter1_337_374_Open_Image.style.display='inline'; Codehighlighter1_337_374_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align="top" />    </span><span id="Codehighlighter1_337_374_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/images/dot.gif" /></span><span id="Codehighlighter1_337_374_Open_Text"><span style="COLOR: #000000">{ </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> RUNTIME_CLASS (class_name); }</span></span><span style="COLOR: #000000"> \</span></div><br />其中，在class#class_name的初始化中和RTTI相关的只有：<br />&amp;name_class用来初始化m_lpszClassName<br />RUNTIME_CLASS(base_class_name)用来初始化CRuntimeClass* m_pBaseClass<br />NULL用来初始化CRuntimeClass* m_pNextClass（此时类别型录还没有建立起来） 
<p>另外，RUNTIME_CLASS就是用来获得class##class_name对象地址的宏：<br /></p><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /><span style="COLOR: #0000ff">#define</span><span style="COLOR: #000000"> RUNTIME_CLASS (class_name) _RUNTIME_CLASS (class_name)</span><span style="COLOR: #000000"><br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #0000ff">#define</span><span style="COLOR: #000000"> _RUNTIME_CLASS (class_name) \</span><span style="COLOR: #000000"><br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />    ((CRuntimeClass</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">) (</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">class_name::</span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">##class_name))</span></div><p>这样，当对程序中的每一个类都使用了DECLARE_DYNAMIC / IMPLEMENT_DYNAMIC宏之后，就为该类在类别型录中进行了登记工作。当然，MFC中所有的类都派生于CObject，所以所有的路线最终都要在CObject处会合，由于CObject没有基类，所以它的CRuntimeClass对象并不能用上面的两个宏来实现，在objcore.cpp中，为CObject的classCObject对象单独作了初始化的工作：</p><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">struct</span><span style="COLOR: #000000"> CRuntimeClass CObject::classCObject </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"><br /><img id="Codehighlighter1_52_107_Open_Image" onclick="this.style.display='none'; Codehighlighter1_52_107_Open_Text.style.display='none'; Codehighlighter1_52_107_Closed_Image.style.display='inline'; Codehighlighter1_52_107_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_52_107_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_52_107_Closed_Text.style.display='none'; Codehighlighter1_52_107_Open_Image.style.display='inline'; Codehighlighter1_52_107_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align="top" /> </span><span id="Codehighlighter1_52_107_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/images/dot.gif" /></span><span id="Codehighlighter1_52_107_Open_Text"><span style="COLOR: #000000">{ </span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">CObject</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">, </span><span style="COLOR: #0000ff">sizeof</span><span style="COLOR: #000000">(CObject), </span><span style="COLOR: #000000">0xffff</span><span style="COLOR: #000000">, NULL, NULL, NULL }</span></span><span style="COLOR: #000000">;</span></div><p>我们可以看到m_pBaseClass被初始化为NULL。另外，也单独实现了GetRuntimeClass():</p><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img id="Codehighlighter1_48_84_Open_Image" onclick="this.style.display='none'; Codehighlighter1_48_84_Open_Text.style.display='none'; Codehighlighter1_48_84_Closed_Image.style.display='inline'; Codehighlighter1_48_84_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_48_84_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_48_84_Closed_Text.style.display='none'; Codehighlighter1_48_84_Open_Image.style.display='inline'; Codehighlighter1_48_84_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align="top" /><span style="COLOR: #000000">CRuntimeClass</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000"> CObject::GetRuntimeClass() </span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000"> </span><span id="Codehighlighter1_48_84_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/images/dot.gif" /></span><span id="Codehighlighter1_48_84_Open_Text"><span style="COLOR: #000000">{<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> _RUNTIME_CLASS (CObject);<br /><img src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span></span></div><br /><p>至于_RUNTIME_CLASS，前面已经说过了。这样，如果想要把自己的类介绍给MFC，只要在类声明中使用DECLARE_DYNAMIC，在类的实现中加入IMPLEMENT_DYNAMIC<br />，就可以把自己注册到类别型录中了。至此，为了实现类对象的RTTI，我们已经做好了所有的准备工作，下面就来看一下它的实现，它主要是靠CObject中的IsKindOf函数完成的。</p><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /><span style="COLOR: #000000">BOOL CObject::IsKindOf(</span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000"> CRuntimeClass</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000"> pClass) </span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000"><br /><img id="Codehighlighter1_58_170_Open_Image" onclick="this.style.display='none'; Codehighlighter1_58_170_Open_Text.style.display='none'; Codehighlighter1_58_170_Closed_Image.style.display='inline'; Codehighlighter1_58_170_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_58_170_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_58_170_Closed_Text.style.display='none'; Codehighlighter1_58_170_Open_Image.style.display='inline'; Codehighlighter1_58_170_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align="top" /></span><span id="Codehighlighter1_58_170_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/images/dot.gif" /></span><span id="Codehighlighter1_58_170_Open_Text"><span style="COLOR: #000000">{<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" /> 　　</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> 为了简洁，略去了不相关的代码</span><span style="COLOR: #008000"><br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" /></span><span style="COLOR: #000000"> 　　CRuntimeClass</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000"> pClassThis </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> GetRuntimeClass();<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" /> 　　</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> pClassThis</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">IsDerivedFrom(pClass);<br /><img src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span></span></div><p>这里，由于GetRuntimeClass是虚函数，所以pClassThis会指向调用IsKindOf函数的类对象的class##class_name，之后利用指向该对象的指针调用IsDerivedFrom：</p><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img id="Codehighlighter1_73_369_Open_Image" onclick="this.style.display='none'; Codehighlighter1_73_369_Open_Text.style.display='none'; Codehighlighter1_73_369_Closed_Image.style.display='inline'; Codehighlighter1_73_369_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_73_369_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_73_369_Closed_Text.style.display='none'; Codehighlighter1_73_369_Open_Image.style.display='inline'; Codehighlighter1_73_369_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align="top" /><span style="COLOR: #000000">BOOL CRuntimeClass::IsDerivedFrom(</span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000"> CRuntimeClass</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000"> pBaseClass) </span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000"> </span><span id="Codehighlighter1_73_369_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/images/dot.gif" /></span><span id="Codehighlighter1_73_369_Open_Text"><span style="COLOR: #000000">{<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">为了简洁，略去了不相关的代码</span><span style="COLOR: #008000"><br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" /></span><span style="COLOR: #000000">    </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> (pBaseClass </span><span style="COLOR: #000000">==</span><span style="COLOR: #000000"> NULL)<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />        </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> FALSE;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" /><br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> simple SI case</span><span style="COLOR: #008000"><br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" /></span><span style="COLOR: #000000">    </span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000"> CRuntimeClass</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000"> pClassThis </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">;<br /><img id="Codehighlighter1_223_314_Open_Image" onclick="this.style.display='none'; Codehighlighter1_223_314_Open_Text.style.display='none'; Codehighlighter1_223_314_Closed_Image.style.display='inline'; Codehighlighter1_223_314_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_223_314_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_223_314_Closed_Text.style.display='none'; Codehighlighter1_223_314_Open_Image.style.display='inline'; Codehighlighter1_223_314_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />    </span><span style="COLOR: #0000ff">while</span><span style="COLOR: #000000"> (pClassThis </span><span style="COLOR: #000000">!=</span><span style="COLOR: #000000"> NULL) </span><span id="Codehighlighter1_223_314_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/images/dot.gif" /></span><span id="Codehighlighter1_223_314_Open_Text"><span style="COLOR: #000000">{<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />        </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> (pClassThis </span><span style="COLOR: #000000">==</span><span style="COLOR: #000000"> pBaseClass)<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />        　</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> TRUE;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />        pClassThis </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> pClassThis</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">m_pBaseClass;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />    }</span></span><span style="COLOR: #000000">    <br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> FALSE;       </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> walked to the top, no match</span><span style="COLOR: #008000"><br /><img src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" /></span><span style="COLOR: #000000">}</span></span></div><br />我们知道，派生类和基类共享基类的static对象，所以在这里，派生类和基类一定共享相同的class##class_name对象，这就为我们判定两个类是否有继承关系提供了理论基础，同样，在IsDerivedFrom中，while循环中的if也的确是这样做的，它沿着该类的同宗路线上行，只要不到共同的祖先CObject，就决不罢休。　<br /><br /><font size="3"><strong>结论</strong></font><br />如果想要把自己的类介绍给MFC，只要在类声明中使用DECLARE_DYNAMIC，在类的实现中加入IMPLEMENT_DYNAMIC<br />，就可以把自己注册到类别型录中了。　　（待续……）</font></span>
<img src ="http://www.cppblog.com/nacci/aggbug/7350.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/nacci/" target="_blank">nacci</a> 2006-05-18 14:53 <a href="http://www.cppblog.com/nacci/archive/2006/05/18/7350.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>回家</title><link>http://www.cppblog.com/nacci/archive/2006/05/16/7246.html</link><dc:creator>nacci</dc:creator><author>nacci</author><pubDate>Tue, 16 May 2006 05:02:00 GMT</pubDate><guid>http://www.cppblog.com/nacci/archive/2006/05/16/7246.html</guid><wfw:comment>http://www.cppblog.com/nacci/comments/7246.html</wfw:comment><comments>http://www.cppblog.com/nacci/archive/2006/05/16/7246.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.cppblog.com/nacci/comments/commentRss/7246.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/nacci/services/trackbacks/7246.html</trackback:ping><description><![CDATA[
		<p>
				<font size="2">        一次工会经历的坎坷想到的。<br /><br /><hr /><br />        离家，是一个过程；回家，是一个过程。开门、关门，这些属于生命里的情节。每日每月每年都有人生的舞台上演出，直到生命的舞台拉下大幕。<br /><br />　　初离家时的那种感觉让人刻苦铭心。不要说离家的理由，为逃避为自由翱翔还是为谋生。我离开了，背起行囊，在心中暗暗发一回誓，然后头也不回地走在不知廷伸到何方的路。尽管知道有关怀的眼睛牵着远去的身影，可还是走下去。走得远了,走得累了，才知道家是圆心，而我们无论到何时都是圆上的一个点，我们离家越远，家对我们的离心率就越大。我们在茫茫人海中沉浮、挣扎，如一只在茫茫风雨中寻觅谷粒的小鸟，深感自己的渺小，这时才感到家的温暖与安全。我们在离家的时候义无反顾，可是离家后，我们又如相思的患者在心中看着家，才知道家是我们一生的渴望。<br /><br />　　回家是一种渴求的心情，那种心情，是离家的延续。被风雨洗礼后的船刻满大海的刀痕，帆破了。船漏了，水手也乏了。只有此时我们才能体会出归心似箭这个词的份量。就如飞倦的鸟儿想要找到自己的巢，折了翅膀在风雨中痛苦地搏击寻觅，想让紧张的神经放个假，让疲惫的精神歇一歇。推门的一刹那，貌的洒脱，骨子里却有与生俱来的软弱与疲乏。本想到家诉说遭受的创伤和委屈，却满脸写着春风得意的笑容与成功的自豪。你踢掉鞋子光着脚在地板上走来走去，你看到你离家时点着的蜡烛还在燃烧，你离家时打开的那本书还放在桌上。你一会儿看看书，一会儿喝几口茶或工点零食吃，你就在温暖中睡一个温馨的觉，攒到足够的力量。<br /><br />留下<br />希望身边的每个人留下<br />每个人的内心都有脆弱的角落<br />现在，请听我说<br />因为我已经成为了伤害你心灵的人<br />就注定要承受心灵孤单的这段日子<br />感谢大家过去做过的一切<br />那些美丽已经永存于心<br />在我的记忆里，强烈渴望和离开说再见<br />心里放声痛哭<br />因为真的很难说再见<br />看着你们伸出双手<br />我相信你们能明白我的心情<br />顺从自己的心情，找到自己的目标<br />不经意掉落的泪水<br />洋溢的爱的光芒<br />因为这里承载着我们现实的梦想<br />在那些最亲爱的记忆里<br />有我们一起创造的奇迹<br />感受到了心灵的呼唤<br />从远方传来的声音，声声不绝<br />那是生命的旋律<br />曾经的声音今天成了美妙的旋律<br />盘桓在心头，久到我们失去记忆<br />即便是那样 <br />我相信，我依旧可以喊出+恋爱之家+这个名字！</font>
				<br />  <a href="http://www.haoo.cn/Html/Article/2005/08/15/442160.html"></a></p>
		<p>
		</p>
		<p>
		</p>
<img src ="http://www.cppblog.com/nacci/aggbug/7246.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/nacci/" target="_blank">nacci</a> 2006-05-16 13:02 <a href="http://www.cppblog.com/nacci/archive/2006/05/16/7246.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>在编译时决定类型的可继承性</title><link>http://www.cppblog.com/nacci/archive/2006/05/15/7200.html</link><dc:creator>nacci</dc:creator><author>nacci</author><pubDate>Mon, 15 May 2006 09:20:00 GMT</pubDate><guid>http://www.cppblog.com/nacci/archive/2006/05/15/7200.html</guid><wfw:comment>http://www.cppblog.com/nacci/comments/7200.html</wfw:comment><comments>http://www.cppblog.com/nacci/archive/2006/05/15/7200.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/nacci/comments/commentRss/7200.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/nacci/services/trackbacks/7200.html</trackback:ping><description><![CDATA[
		<p class="MsoNormal" style="MARGIN: 7.8pt 0cm; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 0cm">
				<span style="FONT-SIZE: 10pt; FONT-FAMILY: 新宋体">一段C++的读书笔记<br /><br /><em>给定任意<span lang="EN-US">2</span>个类型<span lang="EN-US">U</span>和<span lang="EN-US">T</span>，你如何来确定<span lang="EN-US">U</span>是否继承于<span lang="EN-US">T</span>呢？在编译时发现两个类型的这种关系对于泛型库的优化是极为重要的。在泛型函数中，如果某个类实现了特定的接口，你可以根据这种关系为其利用特定的优化算法。另外，如果我们可以在编译期决定<span lang="EN-US">2</span>个类的关系，我们也可以远离<span lang="EN-US">dynamic_cast</span>，从而避免运行时的效率开销。<br /><span lang="EN-US"><?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /?><o:p></o:p></span></em></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 7.8pt 0cm; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 0cm">
				<span style="FONT-SIZE: 10pt; FONT-FAMILY: 新宋体">
						<hr />
						<br />在着手解决这个问题之前，我们先来考虑一个更为一般的问题。假设我们有<span lang="EN-US">2</span>个任意类型<span lang="EN-US">U</span>和<span lang="EN-US">T</span>，如何确定<span lang="EN-US">T</span>能否自动转换成<span lang="EN-US">U</span>呢？<span lang="EN-US"><o:p></o:p></span></span>
		</p>
		<p>
		</p>
		<p>
		</p>
		<p>
		</p>
		<p>
		</p>
		<p class="MsoNormal" style="MARGIN: 7.8pt 0cm; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 0cm">
				<span style="FONT-SIZE: 10pt; FONT-FAMILY: 新宋体">答案也许让你有些惊讶，我们可以利用sizeof来帮忙。你可以把<span lang="EN-US">sizeof</span>用在任何复杂的表达式上，<span lang="EN-US"> sizeof</span>可以返回这个表达式值的大小，而不会在运行时评估表达式的值。这也就意味着，你可以把函数重载、模版实例化、转换规则等等所有你可以在<span lang="EN-US">C++</span>表达式中使用的设施统统塞到<span lang="EN-US">sizeof</span>中来。实际上，<span lang="EN-US">sizeof</span>隐藏了一个可以演绎表达式类型的设施，最终，<span lang="EN-US">sizeof</span>会返回表达式结果的类型。<span lang="EN-US"><o:p></o:p></span></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 7.8pt 0cm; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 0cm">
				<span style="FONT-SIZE: 10pt; FONT-FAMILY: 新宋体">这样我们就可以通过<span lang="EN-US">sizeof</span>和重载函数来解决判断类型之间的可转换性的问题。思路很简单：我们提供<span lang="EN-US">2</span>个重载函数，一个函数的参数是我们要转换成的类型（我们用<span lang="EN-US">U</span>表示），而另一个则用来接收其他所有类型的参数。然后我们把要检测的类型（用<span lang="EN-US">T</span>表示）传递给重载函数。如果接受类型<span lang="EN-US">U</span>为参数的函数被调用了，我们就认为<span lang="EN-US">T</span>可以转换为<span lang="EN-US">U</span>，反之则不可以。如何确定哪个函数被调用了呢？我们利用<span lang="EN-US">sizeof</span>出马，我们只要让重载函数返回不同的类型，然后检查一下返回值就可以了。<span lang="EN-US"><o:p></o:p></span></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 7.8pt 0cm; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 0cm">
				<span style="FONT-SIZE: 10pt; FONT-FAMILY: 新宋体">实践一下：<span lang="EN-US"><o:p></o:p></span></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 7.8pt 0cm; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 0cm">
				<span style="FONT-SIZE: 10pt; FONT-FAMILY: 新宋体">首先，定义<span lang="EN-US">2</span>个不同的类型：<span lang="EN-US"><o:p></o:p></span></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left">
				<span lang="EN-US" style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">
				</span>
		</p>
		<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee">
				<img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />
				<span style="COLOR: #000000">typedef </span>
				<span style="COLOR: #0000ff">char</span>
				<span style="COLOR: #000000"> Small;<br /><img id="Codehighlighter1_30_47_Open_Image" onclick="this.style.display='none'; Codehighlighter1_30_47_Open_Text.style.display='none'; Codehighlighter1_30_47_Closed_Image.style.display='inline'; Codehighlighter1_30_47_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_30_47_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_30_47_Closed_Text.style.display='none'; Codehighlighter1_30_47_Open_Image.style.display='inline'; Codehighlighter1_30_47_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align="top" /></span>
				<span style="COLOR: #0000ff">class</span>
				<span style="COLOR: #000000"> Big </span>
				<span id="Codehighlighter1_30_47_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">
						<img src="http://www.cppblog.com/images/dot.gif" />
				</span>
				<span id="Codehighlighter1_30_47_Open_Text">
						<span style="COLOR: #000000">{ </span>
						<span style="COLOR: #0000ff">char</span>
						<span style="COLOR: #000000"> dummy[</span>
						<span style="COLOR: #000000">2</span>
						<span style="COLOR: #000000">]; }</span>
				</span>
				<span style="COLOR: #000000">;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /></span>
		</div>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left">
				<span style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Lucida Console'; mso-hansi-font-family: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">默认情况下，</span>
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">sizeof(Small)</span>
				<span style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Lucida Console'; mso-hansi-font-family: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">是</span>
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">1</span>
				<span style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Lucida Console'; mso-hansi-font-family: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">，而</span>
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">Big</span>
				<span style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Lucida Console'; mso-hansi-font-family: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">的大小则无关紧要，我们只要知道肯定不是</span>
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">1</span>
				<span style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Lucida Console'; mso-hansi-font-family: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">就好了。</span>
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">
						<o:p>
						</o:p>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 7.8pt 0cm; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 0cm">
				<span style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Lucida Console'; mso-hansi-font-family: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">其次，定义</span>
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">2</span>
				<span style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Lucida Console'; mso-hansi-font-family: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">个重载函数，一个接收要转换成的类型：</span>
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">
						<o:p>
						</o:p>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 7.8pt 0cm; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 0cm">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">Small Test(U);<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 7.8pt 0cm; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 0cm">
				<span style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Lucida Console'; mso-hansi-font-family: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">另一个用来接收“其他的所有类型”，我们要保证在排除所有的转换之后才调用这个函数，</span>
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">OK,</span>
				<span style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Lucida Console'; mso-hansi-font-family: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">用省略号表示的参数列表真好满足需求</span>
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">
						<o:p>
						</o:p>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 7.8pt 0cm; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 0cm">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">Big Test(...);<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 7.8pt 0cm; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 0cm">
				<i style="mso-bidi-font-style: normal">
						<span style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Lucida Console'; mso-hansi-font-family: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">尽管把一个</span>
				</i>
				<i style="mso-bidi-font-style: normal">
						<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">C++</span>
				</i>
				<i style="mso-bidi-font-style: normal">
						<span style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Lucida Console'; mso-hansi-font-family: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">对象传递给</span>
				</i>
				<i style="mso-bidi-font-style: normal">
						<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">...</span>
				</i>
				<i style="mso-bidi-font-style: normal">
						<span style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Lucida Console'; mso-hansi-font-family: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">参数类型的函数，其结果未定义，但是实际上我们并没有调用这个函数。我们甚至可以不用实现它。</span>
				</i>
				<i style="mso-bidi-font-style: normal">
						<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">
								<o:p>
								</o:p>
						</span>
				</i>
		</p>
		<p class="MsoNormal" style="MARGIN: 7.8pt 0cm; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 0cm">
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-no-proof: yes">最后，我们用</span>
				<span lang="EN-US" style="mso-font-kerning: 0pt; mso-no-proof: yes">sizeof</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-no-proof: yes">判断一下就完成任务了：</span>
				<span lang="EN-US" style="mso-font-kerning: 0pt; mso-no-proof: yes">
						<o:p>
						</o:p>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 7.8pt 0cm; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 0cm">
				<span lang="EN-US" style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">
				</span>
		</p>
		<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee">
				<img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />
				<span style="COLOR: #0000ff">const</span>
				<span style="COLOR: #000000"> </span>
				<span style="COLOR: #0000ff">bool</span>
				<span style="COLOR: #000000"> convExist </span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000"> </span>
				<span style="COLOR: #0000ff">sizeof</span>
				<span style="COLOR: #000000">(Test(T())) </span>
				<span style="COLOR: #000000">==</span>
				<span style="COLOR: #000000"> </span>
				<span style="COLOR: #0000ff">sizeof</span>
				<span style="COLOR: #000000">(Small);<br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /></span>
		</div>
		<p class="MsoNormal" style="MARGIN: 7.8pt 0cm; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 0cm">
				<span style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Lucida Console'; mso-hansi-font-family: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">你也许会说，就是它了！</span>
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">Test</span>
				<span style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Lucida Console'; mso-hansi-font-family: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">的调用会创建一个临时对象</span>
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">T</span>
				<span style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Lucida Console'; mso-hansi-font-family: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">，之后可能的结果只能是</span>
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">sizeof(Small)</span>
				<span style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Lucida Console'; mso-hansi-font-family: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">或</span>
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">sizeof(Big)</span>
				<span style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Lucida Console'; mso-hansi-font-family: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">。兴奋之余，我们还要看到一个问题。如果</span>
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">T</span>
				<span style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Lucida Console'; mso-hansi-font-family: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">的构造函数被设计成</span>
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">private</span>
				<span style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Lucida Console'; mso-hansi-font-family: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">，我们就前功尽弃了。当然解决的方法也很简单，定义一个函数，让他返回类型为</span>
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">T</span>
				<span style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Lucida Console'; mso-hansi-font-family: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">的对象。</span>
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">
						<o:p>
						</o:p>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">
				</span>
		</p>
		<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee">
				<img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />
				<span style="COLOR: #000000">T MakeT();<br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /></span>
				<span style="COLOR: #0000ff">const</span>
				<span style="COLOR: #000000"> </span>
				<span style="COLOR: #0000ff">bool</span>
				<span style="COLOR: #000000"> convExist </span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000"> </span>
				<span style="COLOR: #0000ff">sizeof</span>
				<span style="COLOR: #000000">(Test(MakeT())) </span>
				<span style="COLOR: #000000">==</span>
				<span style="COLOR: #000000"> </span>
				<span style="COLOR: #0000ff">sizeof</span>
				<span style="COLOR: #000000">(Small);<br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /></span>
		</div>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Lucida Console'; mso-hansi-font-family: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">最后，把刚才的东西封装到一个类里：</span>
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">
						<o:p>
						</o:p>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left">
				<span lang="EN-US" style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">
				</span>
		</p>
		<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee">
				<img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />
				<span style="COLOR: #000000">template </span>
				<span style="COLOR: #000000">&lt;</span>
				<span style="COLOR: #0000ff">class</span>
				<span style="COLOR: #000000"> T, </span>
				<span style="COLOR: #0000ff">class</span>
				<span style="COLOR: #000000"> U</span>
				<span style="COLOR: #000000">&gt;</span>
				<span style="COLOR: #000000">
						<br />
						<img id="Codehighlighter1_45_250_Open_Image" onclick="this.style.display='none'; Codehighlighter1_45_250_Open_Text.style.display='none'; Codehighlighter1_45_250_Closed_Image.style.display='inline'; Codehighlighter1_45_250_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" />
						<img id="Codehighlighter1_45_250_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_45_250_Closed_Text.style.display='none'; Codehighlighter1_45_250_Open_Image.style.display='inline'; Codehighlighter1_45_250_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align="top" />
				</span>
				<span style="COLOR: #0000ff">class</span>
				<span style="COLOR: #000000"> Conversion </span>
				<span id="Codehighlighter1_45_250_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">
						<img src="http://www.cppblog.com/images/dot.gif" />
				</span>
				<span id="Codehighlighter1_45_250_Open_Text">
						<span style="COLOR: #000000">{<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    typedef </span>
						<span style="COLOR: #0000ff">char</span>
						<span style="COLOR: #000000"> Small;<br /><img id="Codehighlighter1_85_102_Open_Image" onclick="this.style.display='none'; Codehighlighter1_85_102_Open_Text.style.display='none'; Codehighlighter1_85_102_Closed_Image.style.display='inline'; Codehighlighter1_85_102_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_85_102_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_85_102_Closed_Text.style.display='none'; Codehighlighter1_85_102_Open_Image.style.display='inline'; Codehighlighter1_85_102_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />    </span>
						<span style="COLOR: #0000ff">class</span>
						<span style="COLOR: #000000"> Big </span>
						<span id="Codehighlighter1_85_102_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">
								<img src="http://www.cppblog.com/images/dot.gif" />
						</span>
						<span id="Codehighlighter1_85_102_Open_Text">
								<span style="COLOR: #000000">{ </span>
								<span style="COLOR: #0000ff">char</span>
								<span style="COLOR: #000000"> dummy[</span>
								<span style="COLOR: #000000">2</span>
								<span style="COLOR: #000000">]; }</span>
						</span>
						<span style="COLOR: #000000">;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" /><br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    </span>
						<span style="COLOR: #0000ff">static</span>
						<span style="COLOR: #000000"> Small Test(U);<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    </span>
						<span style="COLOR: #0000ff">static</span>
						<span style="COLOR: #000000"> Big Test(<img src="http://www.cppblog.com/images/dot.gif" />);<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    </span>
						<span style="COLOR: #0000ff">static</span>
						<span style="COLOR: #000000"> T MakeT();<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" /><br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" /></span>
						<span style="COLOR: #0000ff">public</span>
						<span style="COLOR: #000000">:<br /><img id="Codehighlighter1_198_247_Open_Image" onclick="this.style.display='none'; Codehighlighter1_198_247_Open_Text.style.display='none'; Codehighlighter1_198_247_Closed_Image.style.display='inline'; Codehighlighter1_198_247_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_198_247_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_198_247_Closed_Text.style.display='none'; Codehighlighter1_198_247_Open_Image.style.display='inline'; Codehighlighter1_198_247_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />    </span>
						<span style="COLOR: #0000ff">enum</span>
						<span style="COLOR: #000000"> </span>
						<span id="Codehighlighter1_198_247_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">
								<img src="http://www.cppblog.com/images/dot.gif" />
						</span>
						<span id="Codehighlighter1_198_247_Open_Text">
								<span style="COLOR: #000000">{ exist </span>
								<span style="COLOR: #000000">=</span>
								<span style="COLOR: #000000"> </span>
								<span style="COLOR: #0000ff">sizeof</span>
								<span style="COLOR: #000000">(Test(MakeT())) </span>
								<span style="COLOR: #000000">==</span>
								<span style="COLOR: #000000"> </span>
								<span style="COLOR: #0000ff">sizeof</span>
								<span style="COLOR: #000000">(Small) }</span>
						</span>
						<span style="COLOR: #000000">;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span>
				</span>
				<span style="COLOR: #000000">;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /></span>
		</div>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left">
				<span style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Lucida Console'; mso-hansi-font-family: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">另外，我们还可以设置另外一个常量</span>
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">Conversion::SameType</span>
				<span style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Lucida Console'; mso-hansi-font-family: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">，如果</span>
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">T</span>
				<span style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Lucida Console'; mso-hansi-font-family: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">和</span>
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">U</span>
				<span style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Lucida Console'; mso-hansi-font-family: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">表示同一个类型，那么返回</span>
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">true</span>
				<span style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Lucida Console'; mso-hansi-font-family: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">：</span>
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">
						<o:p>
						</o:p>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left">
				<span lang="EN-US" style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">
				</span>
		</p>
		<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee">
				<img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />
				<span style="COLOR: #000000">template </span>
				<span style="COLOR: #000000">&lt;</span>
				<span style="COLOR: #0000ff">class</span>
				<span style="COLOR: #000000"> T, </span>
				<span style="COLOR: #0000ff">class</span>
				<span style="COLOR: #000000"> U</span>
				<span style="COLOR: #000000">&gt;</span>
				<span style="COLOR: #000000">
						<br />
						<img id="Codehighlighter1_45_94_Open_Image" onclick="this.style.display='none'; Codehighlighter1_45_94_Open_Text.style.display='none'; Codehighlighter1_45_94_Closed_Image.style.display='inline'; Codehighlighter1_45_94_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" />
						<img id="Codehighlighter1_45_94_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_45_94_Closed_Text.style.display='none'; Codehighlighter1_45_94_Open_Image.style.display='inline'; Codehighlighter1_45_94_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align="top" />
				</span>
				<span style="COLOR: #0000ff">class</span>
				<span style="COLOR: #000000"> Conversion </span>
				<span id="Codehighlighter1_45_94_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">
						<img src="http://www.cppblog.com/images/dot.gif" />
				</span>
				<span id="Codehighlighter1_45_94_Open_Text">
						<span style="COLOR: #000000">{<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    .. </span>
						<span style="COLOR: #0000ff">as</span>
						<span style="COLOR: #000000"> above..<br /><img id="Codehighlighter1_74_92_Open_Image" onclick="this.style.display='none'; Codehighlighter1_74_92_Open_Text.style.display='none'; Codehighlighter1_74_92_Closed_Image.style.display='inline'; Codehighlighter1_74_92_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_74_92_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_74_92_Closed_Text.style.display='none'; Codehighlighter1_74_92_Open_Image.style.display='inline'; Codehighlighter1_74_92_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />    </span>
						<span style="COLOR: #0000ff">enum</span>
						<span style="COLOR: #000000"> </span>
						<span id="Codehighlighter1_74_92_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">
								<img src="http://www.cppblog.com/images/dot.gif" />
						</span>
						<span id="Codehighlighter1_74_92_Open_Text">
								<span style="COLOR: #000000">{ sameType </span>
								<span style="COLOR: #000000">=</span>
								<span style="COLOR: #000000"> </span>
								<span style="COLOR: #0000ff">false</span>
								<span style="COLOR: #000000">}</span>
						</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span>
				</span>
				<span style="COLOR: #000000">;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /></span>
		</div>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left">
				<span style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Lucida Console'; mso-hansi-font-family: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">之后为同一个类型设计一个偏特化版本：</span>
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">
						<o:p>
						</o:p>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left">
				<span lang="FR" style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Lucida Console'; mso-font-kerning: 0pt; mso-ansi-language: FR; mso-no-proof: yes">
				</span>
		</p>
		<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee">
				<img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />
				<span style="COLOR: #000000">template </span>
				<span style="COLOR: #000000">&lt;</span>
				<span style="COLOR: #0000ff">class</span>
				<span style="COLOR: #000000"> T</span>
				<span style="COLOR: #000000">&gt;</span>
				<span style="COLOR: #000000">
						<br />
						<img id="Codehighlighter1_42_83_Open_Image" onclick="this.style.display='none'; Codehighlighter1_42_83_Open_Text.style.display='none'; Codehighlighter1_42_83_Closed_Image.style.display='inline'; Codehighlighter1_42_83_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" />
						<img id="Codehighlighter1_42_83_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_42_83_Closed_Text.style.display='none'; Codehighlighter1_42_83_Open_Image.style.display='inline'; Codehighlighter1_42_83_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align="top" />
				</span>
				<span style="COLOR: #0000ff">class</span>
				<span style="COLOR: #000000"> Conversion</span>
				<span style="COLOR: #000000">&lt;</span>
				<span style="COLOR: #000000">T, T</span>
				<span style="COLOR: #000000">&gt;</span>
				<span style="COLOR: #000000"> </span>
				<span id="Codehighlighter1_42_83_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">
						<img src="http://www.cppblog.com/images/dot.gif" />
				</span>
				<span id="Codehighlighter1_42_83_Open_Text">
						<span style="COLOR: #000000">{<br /><img id="Codehighlighter1_53_80_Open_Image" onclick="this.style.display='none'; Codehighlighter1_53_80_Open_Text.style.display='none'; Codehighlighter1_53_80_Closed_Image.style.display='inline'; Codehighlighter1_53_80_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_53_80_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_53_80_Closed_Text.style.display='none'; Codehighlighter1_53_80_Open_Image.style.display='inline'; Codehighlighter1_53_80_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />    </span>
						<span style="COLOR: #0000ff">enum</span>
						<span style="COLOR: #000000"> </span>
						<span id="Codehighlighter1_53_80_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">
								<img src="http://www.cppblog.com/images/dot.gif" />
						</span>
						<span id="Codehighlighter1_53_80_Open_Text">
								<span style="COLOR: #000000">{ exists </span>
								<span style="COLOR: #000000">=</span>
								<span style="COLOR: #000000"> </span>
								<span style="COLOR: #000000">1</span>
								<span style="COLOR: #000000">, sameType </span>
								<span style="COLOR: #000000">=</span>
								<span style="COLOR: #000000"> </span>
								<span style="COLOR: #000000">1</span>
								<span style="COLOR: #000000"> }</span>
						</span>
						<span style="COLOR: #000000">;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span>
				</span>
				<span style="COLOR: #000000">;<br /></span>
		</div>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left">
				<span style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Lucida Console'; mso-hansi-font-family: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">最后，回到我们的主题，通过</span>
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">Conversion</span>
				<span style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Lucida Console'; mso-hansi-font-family: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">的帮助，我们可以来决定两个类型的继承性了。</span>
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">
						<o:p>
						</o:p>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left">
				<span lang="EN-US" style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">
				</span>
		</p>
		<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; HEIGHT: 66px; BACKGROUND-COLOR: #eeeeee">
				<img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />
				<span style="COLOR: #0000ff">#define</span>
				<span style="COLOR: #000000"> SUPERSUBCLASS(T, U) \</span>
				<span style="COLOR: #000000">
						<br />
						<img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />    (Conversion</span>
				<span style="COLOR: #000000">&lt;</span>
				<span style="COLOR: #0000ff">const</span>
				<span style="COLOR: #000000"> U</span>
				<span style="COLOR: #000000">*</span>
				<span style="COLOR: #000000">, </span>
				<span style="COLOR: #0000ff">const</span>
				<span style="COLOR: #000000"> T</span>
				<span style="COLOR: #000000">*</span>
				<span style="COLOR: #000000">)::exists </span>
				<span style="COLOR: #000000">&amp;&amp;</span>
				<span style="COLOR: #000000"> \<br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />    </span>
				<span style="COLOR: #000000">!</span>
				<span style="COLOR: #000000">Conversion</span>
				<span style="COLOR: #000000">&lt;</span>
				<span style="COLOR: #0000ff">const</span>
				<span style="COLOR: #000000"> T</span>
				<span style="COLOR: #000000">*</span>
				<span style="COLOR: #000000">, </span>
				<span style="COLOR: #0000ff">const</span>
				<span style="COLOR: #000000"> </span>
				<span style="COLOR: #0000ff">void</span>
				<span style="COLOR: #000000">*&gt;</span>
				<span style="COLOR: #000000">::sameType)</span>
		</div>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left">
				<span style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Lucida Console'; mso-hansi-font-family: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">当</span>
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">U</span>
				<span style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Lucida Console'; mso-hansi-font-family: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">继承于</span>
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">T</span>
				<span style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Lucida Console'; mso-hansi-font-family: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">或者</span>
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">U</span>
				<span style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Lucida Console'; mso-hansi-font-family: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">和</span>
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">T</span>
				<span style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Lucida Console'; mso-hansi-font-family: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">是同一个类型的时候，</span>
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">SUPERSUBCLASS</span>
				<span style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Lucida Console'; mso-hansi-font-family: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">返回</span>
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">true</span>
				<span style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Lucida Console'; mso-hansi-font-family: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">。总结一下，只有下面这</span>
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">3</span>
				<span style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Lucida Console'; mso-hansi-font-family: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">种情形</span>
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">const U*</span>
				<span style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Lucida Console'; mso-hansi-font-family: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">可以隐式转换到</span>
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">const T*</span>
				<span style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Lucida Console'; mso-hansi-font-family: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">：</span>
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">
						<o:p>
						</o:p>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; mso-list: l0 level1 lfo1; tab-stops: list 21.0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console'; mso-font-kerning: 0pt; mso-fareast-font-family: 'Lucida Console'; mso-no-proof: yes">
						<span style="mso-list: Ignore">1.<span style="FONT: 7pt 'Times New Roman'">      </span></span>
				</span>
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">T</span>
				<span style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Lucida Console'; mso-hansi-font-family: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">和</span>
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">U</span>
				<span style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Lucida Console'; mso-hansi-font-family: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">是同一个类型</span>
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">
						<o:p>
						</o:p>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; mso-list: l0 level1 lfo1; tab-stops: list 21.0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console'; mso-font-kerning: 0pt; mso-fareast-font-family: 'Lucida Console'; mso-no-proof: yes">
						<span style="mso-list: Ignore">2.<span style="FONT: 7pt 'Times New Roman'">      </span></span>
				</span>
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">T</span>
				<span style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Lucida Console'; mso-hansi-font-family: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">是</span>
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">U</span>
				<span style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Lucida Console'; mso-hansi-font-family: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">的任意一个基类</span>
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">
						<o:p>
						</o:p>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; mso-list: l0 level1 lfo1; tab-stops: list 21.0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console'; mso-font-kerning: 0pt; mso-fareast-font-family: 'Lucida Console'; mso-no-proof: yes">
						<span style="mso-list: Ignore">3.<span style="FONT: 7pt 'Times New Roman'">      </span></span>
				</span>
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">T</span>
				<span style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Lucida Console'; mso-hansi-font-family: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">是</span>
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">void<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 7.8pt 0cm; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 0cm">
				<span style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Lucida Console'; mso-hansi-font-family: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">我们通过第</span>
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">2</span>
				<span style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Lucida Console'; mso-hansi-font-family: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">个测试屏蔽了最后一种情形。当然，如果你认为同一种类型也不算是继承关系的话，可以进一步严格其条件：</span>
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">
						<o:p>
						</o:p>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left">
				<span lang="EN-US" style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">
				</span>
		</p>
		<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee">
				<img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />
				<span style="COLOR: #0000ff">#define</span>
				<span style="COLOR: #000000"> SUPERSUBCLASS_STRICT(T, U) \</span>
				<span style="COLOR: #000000">
						<br />
						<img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />    (SUPERSUBCLASS(T, U) </span>
				<span style="COLOR: #000000">&amp;&amp;</span>
				<span style="COLOR: #000000"> \<br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />    </span>
				<span style="COLOR: #000000">!</span>
				<span style="COLOR: #000000">Conversion(</span>
				<span style="COLOR: #0000ff">const</span>
				<span style="COLOR: #000000"> T, </span>
				<span style="COLOR: #0000ff">const</span>
				<span style="COLOR: #000000"> U)::sameType)</span>
		</div>
<img src ="http://www.cppblog.com/nacci/aggbug/7200.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/nacci/" target="_blank">nacci</a> 2006-05-15 17:20 <a href="http://www.cppblog.com/nacci/archive/2006/05/15/7200.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>