﻿<?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++博客-数不清的日子以来的C++和我-随笔分类-C++漫谈</title><link>http://www.cppblog.com/nacci/category/1784.html</link><description>关于C++的方方面面</description><language>zh-cn</language><lastBuildDate>Mon, 19 May 2008 21:57:46 GMT</lastBuildDate><pubDate>Mon, 19 May 2008 21:57:46 GMT</pubDate><ttl>60</ttl><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>2</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>3</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/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><item><title>C++的静态分派技术</title><link>http://www.cppblog.com/nacci/archive/2005/11/11/1058.html</link><dc:creator>nacci</dc:creator><author>nacci</author><pubDate>Fri, 11 Nov 2005 03:42:00 GMT</pubDate><guid>http://www.cppblog.com/nacci/archive/2005/11/11/1058.html</guid><wfw:comment>http://www.cppblog.com/nacci/comments/1058.html</wfw:comment><comments>http://www.cppblog.com/nacci/archive/2005/11/11/1058.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/nacci/comments/commentRss/1058.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/nacci/services/trackbacks/1058.html</trackback:ping><description><![CDATA[
		<div>
				<span lang="EN-US">
						<font face="Times New Roman" size="2">我们可以用不同的整数来实例化同一个模板，从而构造不同的类型，进而在编译期执行某些抉择。</font>
				</span>
		</div>
		<div>
				<font size="3">
						<span lang="EN-US">
								<font face="Times New Roman">
										<p 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">
										</p>
										<hr id="[object]" />
										<p>
										</p>
								</font>
						</span>
				</font>
				<p 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">
						<font size="2">
								<span lang="EN-US">
										<font face="Times New Roman">Alexandrescu</font>
								</span>
								<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">最初设计的一个简单的模版，现在成了泛型设计的常用手法：</span>
						</font>
				</p>
				<p style="BACKGROUND: #d9d9d9; 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">template</span>
						<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">&lt;<font face="Lucida Console"><span style="COLOR: blue">int</span> v&gt;<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /?><o:p></o:p></font></span>
				</p>
				<p style="BACKGROUND: #d9d9d9; 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">struct</span>
						<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">Int2Type {<o:p></o:p></span>
				</p>
				<p style="BACKGROUND: #d9d9d9; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left">
						<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">
								<font face="Lucida Console">
										<span style="mso-tab-count: 1">    </span>
										<span style="COLOR: blue">enum</span> { value<span style="mso-spacerun: yes">  </span>= v };<o:p></o:p></font>
						</span>
				</p>
				<p style="BACKGROUND: #d9d9d9; MARGIN: 0cm 0cm 0pt">
						<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 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">Int2Type</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">Int2Type&lt;0&gt;</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">Int2Type&lt;1&gt;</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 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">Int2Type</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 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">Int2Type</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 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: Wingdings; mso-bidi-font-family: Wingdings; mso-font-kerning: 0pt; mso-fareast-font-family: Wingdings; mso-no-proof: yes">
								<span style="mso-list: Ignore">
										<font face="Wingdings">l</font>
										<span style="FONT: 7pt 'Times New Roman'">         </span>
								</span>
						</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 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-FAMILY: Wingdings; mso-bidi-font-family: Wingdings; mso-fareast-font-family: Wingdings">
								<span style="mso-list: Ignore">
										<font face="Wingdings" size="3">l</font>
										<span style="FONT: 7pt 'Times New Roman'">         </span>
								</span>
						</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>
				</p>
				<p 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">if-else</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">switch</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">if-else</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 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">NiftyContainer</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 style="BACKGROUND: #d9d9d9; 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">template</span>
						<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">&lt;<font face="Lucida Console"><span style="COLOR: blue">class</span> T&gt; <span style="COLOR: blue">class</span> NiftyContainer {<o:p></o:p></font></span>
				</p>
				<p style="BACKGROUND: #d9d9d9; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left">
						<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">
								<font face="Lucida Console">
										<span style="mso-tab-count: 1">    </span>...<o:p></o:p></font>
						</span>
				</p>
				<p style="BACKGROUND: #d9d9d9; MARGIN: 0cm 0cm 0pt">
						<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 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">NiftyContainer</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">NiftyContainer</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">Clone()</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">bool</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 style="BACKGROUND: #d9d9d9; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left">
						<span lang="EN-US" style="FONT-SIZE: 10pt; BACKGROUND: #d9d9d9; COLOR: blue; FONT-FAMILY: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">template</span>
						<span lang="EN-US" style="FONT-SIZE: 10pt; BACKGROUND: #d9d9d9; FONT-FAMILY: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">&lt;<font face="Lucida Console"><span style="COLOR: blue">class</span> T, <span style="COLOR: blue">bool</span> isPolymorphic&gt; <span style="COLOR: blue">class</span> NiftyContainer {</font></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 style="BACKGROUND: #d9d9d9; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left">
						<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">
								<font face="Lucida Console">
										<span style="mso-tab-count: 1">    </span>
										<span style="COLOR: green">// Other actions<o:p></o:p></span>
								</font>
						</span>
				</p>
				<p style="BACKGROUND: #d9d9d9; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left">
						<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">
								<font face="Lucida Console">
										<span style="mso-tab-count: 1">    </span>
										<span style="COLOR: blue">void</span> DoSomething() {<o:p></o:p></font>
						</span>
				</p>
				<p style="BACKGROUND: #d9d9d9; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left">
						<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">
								<font face="Lucida Console">
										<span style="mso-tab-count: 2">       </span>T* pSomeObj = ...;<o:p></o:p></font>
						</span>
				</p>
				<p style="BACKGROUND: #d9d9d9; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left">
						<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">
								<font face="Lucida Console">
										<span style="mso-tab-count: 2">       </span>
										<span style="COLOR: blue">if</span>(isPolymorphic) {<o:p></o:p></font>
						</span>
				</p>
				<p style="BACKGROUND: #d9d9d9; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left">
						<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">
								<font face="Lucida Console">
										<span style="mso-tab-count: 3">           </span>T* pNewObj = pSomeObj-&gt;Clone();<o:p></o:p></font>
						</span>
				</p>
				<p style="BACKGROUND: #d9d9d9; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left">
						<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">
								<font face="Lucida Console">
										<span style="mso-tab-count: 3">           </span>
										<span style="COLOR: green">// Some polymorphic algorithm<o:p></o:p></span>
								</font>
						</span>
				</p>
				<p style="BACKGROUND: #d9d9d9; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left">
						<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">
								<font face="Lucida Console">
										<span style="mso-tab-count: 2">       </span>}<o:p></o:p></font>
						</span>
				</p>
				<p style="BACKGROUND: #d9d9d9; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left">
						<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">
								<font face="Lucida Console">
										<span style="mso-tab-count: 2">       </span>
										<span style="COLOR: blue">else</span> {<o:p></o:p></font>
						</span>
				</p>
				<p style="BACKGROUND: #d9d9d9; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left">
						<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">
								<font face="Lucida Console">
										<span style="mso-tab-count: 3">           </span>T* pNewObj = <span style="COLOR: blue">new</span> T(*pSomeObj);<o:p></o:p></font>
						</span>
				</p>
				<p style="BACKGROUND: #d9d9d9; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left">
						<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">
								<font face="Lucida Console">
										<span style="mso-tab-count: 3">           </span>
										<span style="COLOR: green">// Some non-polymorphic algorithm<o:p></o:p></span>
								</font>
						</span>
				</p>
				<p style="BACKGROUND: #d9d9d9; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left">
						<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">
								<font face="Lucida Console">
										<span style="mso-tab-count: 2">       </span>}<o:p></o:p></font>
						</span>
				</p>
				<p style="BACKGROUND: #d9d9d9; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left">
						<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">
								<font face="Lucida Console">
										<span style="mso-tab-count: 1">    </span>}<o:p></o:p></font>
						</span>
				</p>
				<p style="BACKGROUND: #d9d9d9; MARGIN: 0cm 0cm 0pt">
						<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 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">Clone()</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">NiftyContainer::DoSomething</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">NiftyContainer&lt;int, false&gt;::DoSomething</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">pObj-&gt;Clone()</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 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">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">new T(*pObj)</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 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">
								<o:p>
								</o:p>
						</span>
				</p>
				<p 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">Int2Type</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">false</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">Int2Type&lt;isPolymorphic&gt;</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 style="BACKGROUND: #d9d9d9; 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">template</span>
						<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">&lt;<font face="Lucida Console"><span style="COLOR: blue">class</span> T, <span style="COLOR: blue">bool</span> isPolymorphic&gt; <span style="COLOR: blue">class</span> NiftyContainer {<o:p></o:p></font></span>
				</p>
				<p style="BACKGROUND: #d9d9d9; 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">private</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 style="BACKGROUND: #d9d9d9; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left">
						<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">
								<font face="Lucida Console">
										<span style="mso-tab-count: 1">    </span>
										<span style="COLOR: green">// Other actions<o:p></o:p></span>
								</font>
						</span>
				</p>
				<p style="BACKGROUND: #d9d9d9; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left">
						<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">
								<font face="Lucida Console">
										<span style="mso-tab-count: 1">    </span>
										<span style="COLOR: blue">void</span> DoSomething(T* pObj, Int2Type&lt;<span style="COLOR: blue">true</span>&gt;) {<o:p></o:p></font>
						</span>
				</p>
				<p style="BACKGROUND: #d9d9d9; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left">
						<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">
								<font face="Lucida Console">
										<span style="mso-tab-count: 2">       </span>T* pNewObj = pSomeObj-&gt;Clone();<o:p></o:p></font>
						</span>
				</p>
				<p style="BACKGROUND: #d9d9d9; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left">
						<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">
								<font face="Lucida Console">
										<span style="mso-tab-count: 2">       </span>
										<span style="COLOR: green">// Some polymorphic algorithm<o:p></o:p></span>
								</font>
						</span>
				</p>
				<p style="BACKGROUND: #d9d9d9; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left">
						<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">
								<font face="Lucida Console">
										<span style="mso-tab-count: 1">    </span>}<o:p></o:p></font>
						</span>
				</p>
				<p style="BACKGROUND: #d9d9d9; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left">
						<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">
								<font face="Lucida Console">
										<span style="mso-tab-count: 1">    </span>
										<span style="COLOR: blue">void</span> DoSomething(T* pObj, Int2Type&lt;<span style="COLOR: blue">false</span>&gt;) {<o:p></o:p></font>
						</span>
				</p>
				<p style="BACKGROUND: #d9d9d9; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left">
						<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">
								<font face="Lucida Console">
										<span style="mso-tab-count: 2">       </span>T* pNewObj = <span style="COLOR: blue">new</span> T(*pSomeObj);<o:p></o:p></font>
						</span>
				</p>
				<p style="BACKGROUND: #d9d9d9; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left">
						<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">
								<font face="Lucida Console">
										<span style="mso-tab-count: 2">       </span>
										<span style="COLOR: green">// Some non-polymorphic algorithm<o:p></o:p></span>
								</font>
						</span>
				</p>
				<p style="BACKGROUND: #d9d9d9; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left">
						<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">
								<font face="Lucida Console">
										<span style="mso-tab-count: 1">    </span>}<o:p></o:p></font>
						</span>
				</p>
				<p style="BACKGROUND: #d9d9d9; 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">public</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 style="BACKGROUND: #d9d9d9; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left">
						<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">
								<font face="Lucida Console">
										<span style="mso-tab-count: 1">    </span>
										<span style="COLOR: blue">void</span> DoSomething(T* pObj) {<o:p></o:p></font>
						</span>
				</p>
				<p style="BACKGROUND: #d9d9d9; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left">
						<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">
								<font face="Lucida Console">
										<span style="mso-tab-count: 2">       </span>DoSomething(pObj, Int2Type&lt;isPolymorphic&gt;());<o:p></o:p></font>
						</span>
				</p>
				<p style="BACKGROUND: #d9d9d9; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left">
						<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">
								<font face="Lucida Console">
										<span style="mso-tab-count: 1">    </span>}<o:p></o:p></font>
						</span>
				</p>
				<p style="BACKGROUND: #d9d9d9; MARGIN: 0cm 0cm 0pt">
						<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 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">Int2Type</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>
		</div>
<img src ="http://www.cppblog.com/nacci/aggbug/1058.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> 2005-11-11 11:42 <a href="http://www.cppblog.com/nacci/archive/2005/11/11/1058.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>只在多态基类中声明虚析构函数</title><link>http://www.cppblog.com/nacci/archive/2005/11/10/1046.html</link><dc:creator>nacci</dc:creator><author>nacci</author><pubDate>Thu, 10 Nov 2005 08:43:00 GMT</pubDate><guid>http://www.cppblog.com/nacci/archive/2005/11/10/1046.html</guid><wfw:comment>http://www.cppblog.com/nacci/comments/1046.html</wfw:comment><comments>http://www.cppblog.com/nacci/archive/2005/11/10/1046.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.cppblog.com/nacci/comments/commentRss/1046.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/nacci/services/trackbacks/1046.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 关于virtual desctructor的详细讨论。同样来自于《Effective C++》3rd Edition。																														跟踪时间是很平常的任务，所以开发一个名为										TimeKeeper								的基类，并让不同的派生类来实现不同的计时方法是很合理的事情：					...&nbsp;&nbsp;<a href='http://www.cppblog.com/nacci/archive/2005/11/10/1046.html'>阅读全文</a><img src ="http://www.cppblog.com/nacci/aggbug/1046.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> 2005-11-10 16:43 <a href="http://www.cppblog.com/nacci/archive/2005/11/10/1046.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>浅析C++ Compile-time Assertion技术</title><link>http://www.cppblog.com/nacci/archive/2005/11/07/969.html</link><dc:creator>nacci</dc:creator><author>nacci</author><pubDate>Mon, 07 Nov 2005 15:10:00 GMT</pubDate><guid>http://www.cppblog.com/nacci/archive/2005/11/07/969.html</guid><wfw:comment>http://www.cppblog.com/nacci/comments/969.html</wfw:comment><comments>http://www.cppblog.com/nacci/archive/2005/11/07/969.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.cppblog.com/nacci/comments/commentRss/969.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/nacci/services/trackbacks/969.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 你可能经常需要利用运行时断言技术，它可以方便地测试前提条件。但是，随着Metaprogramming概念的出现，编译时断言技术也已经和runtime assertion一样的普遍了。如何在编译时进行断言呢？其实，方法只有一个，就是让编译器生成一条错误信息，但是编译器生成的错误信息信息性往往有又理想。并且，即使你在一种编译上设计了一种方案，你也很难把它移植到其他的编译器上。我们通过其实现方法的改进和...&nbsp;&nbsp;<a href='http://www.cppblog.com/nacci/archive/2005/11/07/969.html'>阅读全文</a><img src ="http://www.cppblog.com/nacci/aggbug/969.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> 2005-11-07 23:10 <a href="http://www.cppblog.com/nacci/archive/2005/11/07/969.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C++的类型萃取技术</title><link>http://www.cppblog.com/nacci/archive/2005/11/03/911.html</link><dc:creator>nacci</dc:creator><author>nacci</author><pubDate>Thu, 03 Nov 2005 02:03:00 GMT</pubDate><guid>http://www.cppblog.com/nacci/archive/2005/11/03/911.html</guid><wfw:comment>http://www.cppblog.com/nacci/comments/911.html</wfw:comment><comments>http://www.cppblog.com/nacci/archive/2005/11/03/911.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cppblog.com/nacci/comments/commentRss/911.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/nacci/services/trackbacks/911.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 自从C++中引入了template后，以泛型技术为中心的设计得到了长足的进步。STL就是这个阶段杰出的产物。STL的目标就是要把数据和算法分开，分别对其进行设计，之后通过一种名为iterator的东西，把这二者再粘接到一起。设计模式中，关于iterator的描述为：一种能够顺序访问容器中每个元素的方法，使用该方法不能暴露容器内部的表达方式。可以说，类型萃取技术就是为了要解决和iterator有关的...&nbsp;&nbsp;<a href='http://www.cppblog.com/nacci/archive/2005/11/03/911.html'>阅读全文</a><img src ="http://www.cppblog.com/nacci/aggbug/911.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> 2005-11-03 10:03 <a href="http://www.cppblog.com/nacci/archive/2005/11/03/911.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C++默认会为我们做些什么工作？</title><link>http://www.cppblog.com/nacci/archive/2005/11/03/910.html</link><dc:creator>nacci</dc:creator><author>nacci</author><pubDate>Thu, 03 Nov 2005 01:17:00 GMT</pubDate><guid>http://www.cppblog.com/nacci/archive/2005/11/03/910.html</guid><wfw:comment>http://www.cppblog.com/nacci/comments/910.html</wfw:comment><comments>http://www.cppblog.com/nacci/archive/2005/11/03/910.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cppblog.com/nacci/comments/commentRss/910.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/nacci/services/trackbacks/910.html</trackback:ping><description><![CDATA[
		<p>
				<span style="FONT-SIZE: 10pt; FONT-FAMILY: 新宋体">2005年5月份,Scott Mayers发布了《Effective C++》第三版。作者根据当前C++的特点和设计模式，对第二版中半数以上的内容作了更新。此等佳作，不敢独享，以肆同好。 
<hr id="[object]" /><p></p></span>
		</p>
		<p 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: 新宋体">什么时候一个空的<font face="新宋体"><span lang="EN-US">class</span>不是空的？<span lang="EN-US">C++</span>会在何时做些什么事情？如果你不声明它们，编译器会为你声明它们自己的拷贝构造函数、一个赋值运算符和一个析构函数。另外，如果你不声明一个构造函数，编译器还会为你创建一个。所有这些自动生成的函数都是<span lang="EN-US">public</span>和<span lang="EN-US">inline</span>的。例如，如果你写下：<span lang="EN-US"><?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /?><o:p></o:p></span></font></span>
		</p>
		<p style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; BACKGROUND: #d9d9d9; COLOR: blue; FONT-FAMILY: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">class</span>
				<span lang="EN-US" style="FONT-SIZE: 10pt; BACKGROUND: #d9d9d9; FONT-FAMILY: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes"> Empty {};</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 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: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">这和你写下如下的代码本质上是一样的：</span>
				<span lang="EN-US" style="FONT-SIZE: 10pt">
						<o:p>
						</o:p>
				</span>
		</p>
		<p style="BACKGROUND: #d9d9d9; 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">class</span>
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes"> Empty {<o:p></o:p></span>
		</p>
		<p style="BACKGROUND: #d9d9d9; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">
						<font face="Lucida Console">
								<span style="mso-tab-count: 1">    </span>Empty() {…} <span style="COLOR: green">// default constructor<o:p></o:p></span></font>
				</span>
		</p>
		<p style="BACKGROUND: #d9d9d9; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">
						<font face="Lucida Console">
								<span style="mso-tab-count: 1">    </span>Empty(<span style="COLOR: blue">const</span> Empty&amp; rhs) {…} <span style="COLOR: green">// Copy constructor<o:p></o:p></span></font>
				</span>
		</p>
		<p style="BACKGROUND: #d9d9d9; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">
						<font face="Lucida Console">
								<span style="mso-tab-count: 1">    </span>~Empty() {…}<span style="mso-tab-count: 1">  </span><span style="COLOR: green">// destructor - whether it's virtual?<o:p></o:p></span></font>
				</span>
		</p>
		<p style="BACKGROUND: #d9d9d9; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">
						<font face="Lucida Console">
								<span style="mso-tab-count: 1">    </span>
								<o:p>
								</o:p>
						</font>
				</span>
		</p>
		<p style="BACKGROUND: #d9d9d9; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">
						<font face="Lucida Console">
								<span style="mso-tab-count: 1">    </span>
								<span style="COLOR: green">// copy assignment operator<o:p></o:p></span>
						</font>
				</span>
		</p>
		<p style="BACKGROUND: #d9d9d9; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">
						<font face="Lucida Console">
								<span style="mso-tab-count: 1">    </span>Empty&amp; <span style="COLOR: blue">operator</span>=(<span style="COLOR: blue">const</span> Empty&amp; rhs) {}<o:p></o:p></font>
				</span>
		</p>
		<p style="BACKGROUND: #d9d9d9; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left">
				<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 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: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">当然，这些函数只有它们真正被需要的时候才会被创建。下面这些情况会使得这些函数被创建：</span>
				<span lang="EN-US" style="FONT-SIZE: 10pt">
						<o:p>
						</o:p>
				</span>
		</p>
		<p style="BACKGROUND: #d9d9d9; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">Empty e1; <span style="COLOR: green"><font face="Lucida Console">// default constructor &amp; destructor<o:p></o:p></font></span></span>
		</p>
		<p style="BACKGROUND: #d9d9d9; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">Empty e2(e1); <span style="COLOR: green"><font face="Lucida Console">// copy constructor<o:p></o:p></font></span></span>
		</p>
		<p style="BACKGROUND: #d9d9d9; MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">e2 = e1; <span style="COLOR: green"><font face="Lucida Console">// copy assignment operator<o:p></o:p></font></span></span>
		</p>
		<p 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; COLOR: black; FONT-FAMILY: 新宋体; mso-font-kerning: 0pt; mso-no-proof: yes">既然编译器会为你创建这些函数，那么这些函数都做些什么工作呢？默认的构造和析构函数主要是让编译器放置一些执行“幕后工作”的代码，例如调用基类和非静态数据成员的构造和析构函数等。需要注意的是编译器为你生成的这个析构函数并不是虚拟的，除非这个类的基类明确声明了一个虚拟的析构函数。<span lang="EN-US"><o:p></o:p></span></span>
		</p>
		<p 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; COLOR: black; FONT-FAMILY: 新宋体; mso-font-kerning: 0pt; mso-no-proof: yes">对于拷贝构造函数和赋值运算符，编译器生成的版本只是简单的<font face="新宋体"><span lang="EN-US">copy</span>每一个非静态数据成员。例如，考虑一个名为<span lang="EN-US">NamedObject</span>的模板<span lang="EN-US">,</span>它可以让你把名字和类型<span lang="EN-US">T</span>关联起来。</font></span>
				<span lang="EN-US" style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">
						<o:p>
						</o:p>
				</span>
		</p>
		<p style="BACKGROUND: #d9d9d9; 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">template</span>
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes"> &lt;<font face="Lucida Console"><span style="COLOR: blue">typename</span> T&gt;<o:p></o:p></font></span>
		</p>
		<p style="BACKGROUND: #d9d9d9; 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">class</span>
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes"> NamedObject {<o:p></o:p></span>
		</p>
		<p style="BACKGROUND: #d9d9d9; 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">public</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 style="BACKGROUND: #d9d9d9; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">
						<font face="Lucida Console">
								<span style="mso-tab-count: 1">    </span>NamedObject(<span style="COLOR: blue">const</span><span style="COLOR: blue">char</span>* name, <span style="COLOR: blue">const</span> T&amp; value);<o:p></o:p></font>
				</span>
		</p>
		<p style="BACKGROUND: #d9d9d9; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">
						<font face="Lucida Console">
								<span style="mso-tab-count: 1">    </span>NamedObject(<span style="COLOR: blue">const</span> std::string&amp; name, <span style="COLOR: blue">const</span> T&amp; value);<o:p></o:p></font>
				</span>
		</p>
		<p style="BACKGROUND: #d9d9d9; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left">
				<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 style="BACKGROUND: #d9d9d9; 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">private</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 style="BACKGROUND: #d9d9d9; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">
						<font face="Lucida Console">
								<span style="mso-tab-count: 1">    </span>std::string nameValue;<o:p></o:p></font>
				</span>
		</p>
		<p style="BACKGROUND: #d9d9d9; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">
						<font face="Lucida Console">
								<span style="mso-tab-count: 1">    </span>T objectValue;<o:p></o:p></font>
				</span>
		</p>
		<p style="BACKGROUND: #d9d9d9; MARGIN: 0cm 0cm 0pt">
				<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 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-font-kerning: 0pt; mso-no-proof: yes">由于<font face="新宋体"><span lang="EN-US">NamedObject</span>中声明了构造函数，编译器便不会再自做主张为你生成一个默认的。这是很重要的。这意味着如果你精心设计的类的构造方式，你就不用再去担心编译器会愚蠢的为你添加一个不带参数的构造函数而破坏你的设计。<span lang="EN-US"><o:p></o:p></span></font></span>
		</p>
		<p 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: 新宋体; mso-font-kerning: 0pt; mso-no-proof: yes">NamedObject</span>
				<span style="FONT-SIZE: 10pt; FONT-FAMILY: 新宋体; mso-font-kerning: 0pt; mso-no-proof: yes">中既没有声明拷贝构造函数也没有声明赋值运算符，所以当需要的时候，编译器会自动为你生成。显然，下面的代码需要拷贝构造函数的支持：<span lang="EN-US"><o:p></o:p></span></span>
		</p>
		<p style="BACKGROUND: #d9d9d9; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">NamedObject&lt;<font face="Lucida Console"><span style="COLOR: blue">int</span>&gt; no1(<span style="COLOR: maroon">"Smallest Prime Number"</span>, 2);<o:p></o:p></font></span>
		</p>
		<p style="BACKGROUND: #d9d9d9; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left" align="left">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">NamedObject&lt;<font face="Lucida Console"><span style="COLOR: blue">int</span>&gt; no2(no1);<o:p></o:p></font></span>
		</p>
		<p 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; COLOR: black; FONT-FAMILY: 新宋体">编译器生成的拷贝构造函数必须要使用<font face="新宋体"><span lang="EN-US">no1.nameValue</span>和<span lang="EN-US">no1.objectValue</span>来初始化<span lang="EN-US">no2</span>中对应的成员。由于<span lang="EN-US">nameValue</span>的类型是<span lang="EN-US">string</span>，并且标准的<span lang="EN-US">string</span>有一个拷贝构造函数，所以<span lang="EN-US">no2.nameValue</span>就可以通过<span lang="EN-US">string</span>的拷贝构造函数完成。另外<span lang="EN-US">objectValue</span>是一个整数，对于这个内置类型，简单的<span lang="EN-US">bit-copy</span>就可以完成复制的任务了。<span lang="EN-US"><o:p></o:p></span></font></span>
		</p>
		<p 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; COLOR: black; FONT-FAMILY: 新宋体">其实，如果需要的话，编译器会按照和上面提到的相同的手法来为<font face="新宋体"><span lang="EN-US">NamedObject<int></int></span>来生成一个赋值运算符。但是，只有当生成的代码在语法和语义都都正确的时候，编译器才会为你执行生成工作，如果其中任何一方面除了问题，编译器就会拒绝为你重载<span lang="EN-US">operator =</span>。<span lang="EN-US"><o:p></o:p></span></font></span>
		</p>
		<p 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; COLOR: black; FONT-FAMILY: 新宋体">例如：如果我们这样定义<font face="新宋体"><span lang="EN-US">NamedObject</span>：<span lang="EN-US"><o:p></o:p></span></font></span>
		</p>
		<p style="BACKGROUND: #d9d9d9; 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">template</span>
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes"> &lt;<font face="Lucida Console"><span style="COLOR: blue">typename</span> T&gt;<o:p></o:p></font></span>
		</p>
		<p style="BACKGROUND: #d9d9d9; 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">class</span>
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes"> NamedObject {<o:p></o:p></span>
		</p>
		<p style="BACKGROUND: #d9d9d9; 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">public</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 style="BACKGROUND: #d9d9d9; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">
						<font face="Lucida Console">
								<span style="mso-tab-count: 1">    </span>NamedObject(<span style="COLOR: blue">const</span> std::string&amp; name, <span style="COLOR: blue">const</span> T&amp; value);<o:p></o:p></font>
				</span>
		</p>
		<p style="BACKGROUND: #d9d9d9; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left">
				<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 style="BACKGROUND: #d9d9d9; 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">private</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 style="BACKGROUND: #d9d9d9; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">
						<font face="Lucida Console">
								<span style="mso-tab-count: 1">    </span>std::string&amp; nameValue;<o:p></o:p></font>
				</span>
		</p>
		<p style="BACKGROUND: #d9d9d9; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">
						<font face="Lucida Console">
								<span style="mso-tab-count: 1">    </span>
								<span style="COLOR: blue">const</span> T objectValue;<br /></font>
				</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 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-font-kerning: 0pt; mso-no-proof: yes; mso-ascii-font-family: 'Lucida Console'; mso-hansi-font-family: 'Lucida Console'">之后，下面的代码会怎样呢？</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 style="BACKGROUND: #d9d9d9; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">std::string newDog(<font face="Lucida Console"><span style="COLOR: maroon">"Persephone"</span>);<o:p></o:p></font></span>
		</p>
		<p style="BACKGROUND: #d9d9d9; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">std::string oldDog(<font face="Lucida Console"><span style="COLOR: maroon">"Satch"</span>);<o:p></o:p></font></span>
		</p>
		<p style="BACKGROUND: #d9d9d9; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">NamedObject&lt;<font face="Lucida Console"><span style="COLOR: blue">int</span>&gt; p(newDog, 2);<o:p></o:p></font></span>
		</p>
		<p style="BACKGROUND: #d9d9d9; MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left">
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">NamedObject&lt;<font face="Lucida Console"><span style="COLOR: blue">int</span>&gt; s(oldDog, 36);<br /></font></span>
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-font-kerning: 0pt; mso-no-proof: yes">p = s;<font face="Lucida Console"><span style="COLOR: green"> // What should happen?</span><o:p></o:p></font></span>
		</p>
		<p 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; COLOR: black; FONT-FAMILY: 新宋体">在复制前，<font face="新宋体"><span lang="EN-US">p.nameValue</span>和<span lang="EN-US">s.nameValue</span>分别指向不同的<span lang="EN-US">string</span>对象。这个复制应该对<span lang="EN-US">p.nameValue</span>做怎样的改变呢？直觉上，<span lang="EN-US">p.nameValue</span>将会指向<span lang="EN-US">s.nameValue</span>所指的<span lang="EN-US">string</span>对象。但是这破坏了<span lang="EN-US">C++</span>的一条基本的准则，<span lang="EN-US">C++</span>不允许引用指向不同的对象。换句话说，难道改变<span lang="EN-US">p.nameValue</span>所引用的对象应该要影响到其它对象所引用的字符串吗？这是编译器生成的赋值运算符应该做的事情吗？<span lang="EN-US"><o:p></o:p></span></font></span>
		</p>
		<p 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: black; FONT-FAMILY: 新宋体">C++</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 新宋体">对于这个问题的解答方法是拒绝编译这样的代码。如果你想让含有引用数据成员的类支持赋值功能，那么你就必须自己定义赋值运算符。对于含有<font face="新宋体"><span lang="EN-US">const</span>数据成员的类来说，故事是类似的。修改对象中的<span lang="EN-US">const</span>成员总是非法的，所以编译器对于如何处理这种问题一无所知。最后，如果基类把<span lang="EN-US">operator=</span>声明为<span lang="EN-US">private</span>，那么编译器同样会拒绝为派生类生成<span lang="EN-US">operator=</span>。毕竟，一方面，即便编译器可以生成，<span lang="EN-US">operator=</span>也只能处理派生类中属于基类的那一部分；另一方面，派生类也根本无权访问基类中的<span lang="EN-US">private</span>成员。<span lang="EN-US"><o:p></o:p></span></font></span>
		</p>
		<p 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">
				<b style="mso-bidi-font-weight: normal">
						<span style="FONT-SIZE: 14pt; COLOR: black; FONT-FAMILY: 新宋体">时时刻刻让自己记住<span lang="EN-US"><o:p></o:p></span></span>
				</b>
		</p>
		<p style="MARGIN: 7.8pt 0cm 7.8pt 21pt; TEXT-INDENT: -21pt; mso-para-margin-top: .5gd; mso-para-margin-right: 0cm; mso-para-margin-bottom: .5gd; mso-para-margin-left: 21.0pt; mso-list: l0 level1 lfo1; tab-stops: list 21.0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Wingdings; mso-fareast-font-family: Wingdings; mso-bidi-font-family: Wingdings">
						<span style="mso-list: Ignore">
								<font face="Wingdings">l</font>
								<span style="FONT: 7pt 'Times New Roman'">         </span>
						</span>
				</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 新宋体">编译器会在必要的时候隐式生成类的默认构造函数、拷贝构造函数、<font face="新宋体"><span lang="EN-US">operator=</span>和析构函数。<span lang="EN-US"><o:p></o:p></span></font></span>
		</p>
<img src ="http://www.cppblog.com/nacci/aggbug/910.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> 2005-11-03 09:17 <a href="http://www.cppblog.com/nacci/archive/2005/11/03/910.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>