﻿<?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++ Programmer's Cookbook-随笔分类-CPlusPlus</title><link>http://www.cppblog.com/mzty/category/199.html</link><description>&lt;br/&gt;  
&lt;br/&gt;
&lt;a href = "http://www.cppblog.com/mzty/archive/2007/03/02/19109.html"&gt;&lt;font size = 5 color ="#00FFFF"&gt;{C++ 基础}&lt;font/&gt;&lt;/a&gt;

&lt;a href = "http://www.cppblog.com/mzty/archive/2007/08/13/29922.html"&gt;&lt;font size = 5 color ="#00FFFF"&gt;{C++ 高级}&lt;font/&gt;&lt;/a&gt;

&lt;a href = "http://www.cppblog.com/mzty/archive/2008/07/18/56532.html"&gt;&lt;font size = 5 color ="#00FFFF"&gt;{C++/CLI}&lt;font/&gt;&lt;/a&gt;

&lt;a href = "http://www.cppblog.com/mzty/archive/2008/07/18/56533.html"&gt;&lt;font size = 5 color ="#00FFFF"&gt;{VC Team中文}&lt;font/&gt;&lt;/a&gt;

&lt;a href = "http://www.cppblog.com/mzty/archive/2007/04/16/22064.html"&gt;&lt;font size = 5 color ="#00FFFF"&gt;{C#界面，C++核心算法}&lt;font/&gt;&lt;/a&gt;

&lt;a href = "http://www.cppblog.com/mzty/archive/2007/03/04/19163.html"&gt;&lt;font size = 5 color ="#00FFFF"&gt;{设计模式}&lt;font/&gt;&lt;/a&gt;

&lt;a href = "
http://www.cppblog.com/mzty/archive/2007/03/04/19167.html"&gt;&lt;font size = 5 color ="#FF0000"&gt;{C#基础}&lt;font/&gt;&lt;/a&gt;





</description><language>zh-cn</language><lastBuildDate>Tue, 29 Jul 2008 19:19:56 GMT</lastBuildDate><pubDate>Tue, 29 Jul 2008 19:19:56 GMT</pubDate><ttl>60</ttl><item><title>《windows via C++》之windows线程同步</title><link>http://www.cppblog.com/mzty/archive/2008/07/29/57470.html</link><dc:creator>梦在天涯</dc:creator><author>梦在天涯</author><pubDate>Tue, 29 Jul 2008 14:54:00 GMT</pubDate><guid>http://www.cppblog.com/mzty/archive/2008/07/29/57470.html</guid><wfw:comment>http://www.cppblog.com/mzty/comments/57470.html</wfw:comment><comments>http://www.cppblog.com/mzty/archive/2008/07/29/57470.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/mzty/comments/commentRss/57470.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mzty/services/trackbacks/57470.html</trackback:ping><description><![CDATA[<p><br>来自：梦在天涯C++博客(<a href="http://www.cppblog.com/mzty/">http://www.cppblog.com/mzty/</a>)</p>
<p>一 线程</p>
<p>1）如果你正在编写C/C++代码，决不应该调用CreateThread。相反，应该使用VisualC++运行期库函数_beginthreadex，退出也应该使用_endthreadex。如果不使用Microsoft的VisualC++编译器，你的编译器供应商有它自己的CreateThred替代函数。不管这个替代函数是什么，你都必须使用。</p>
<p><br>2）因为_beginthreadex和_endthreadex是CRT线程函数，所以必须注意编译选项runtimelibaray的选择，使用MT或MTD。</p>
<p>3) _beginthreadex函数的参数列表与CreateThread函数的参数列表是相同的，但是参数名和类型并不完全相同。这是因为Microsoft的C/C++运行期库的开发小组认为，C/C++运行期函数不应该对Windows数据类型有任何依赖。_beginthreadex函数也像CreateThread那样，返回新创建的线程的句柄。</p>
<p>4）下面是关于_beginthreadex的一些要点：</p>
<p>&#8226;每个线程均获得由C/C++运行期库的堆栈分配的自己的tiddata内存结构。（tiddata结构位于Mtdll.h文件中的VisualC++源代码中）。</p>
<p>&#8226;传递给_beginthreadex的线程函数的地址保存在tiddata内存块中。传递给该函数的参数也保存在该数据块中。</p>
<p>&#8226;_beginthreadex确实从内部调用CreateThread，因为这是操作系统了解如何创建新线程的唯一方法。</p>
<p>&#8226;当调用CreatetThread时，它被告知通过调用_threadstartex而不是pfnStartAddr来启动执行新线程。还有，传递给线程函数的参数是tiddata结构而不是pvParam的地址。</p>
<p>&#8226;如果一切顺利，就会像CreateThread那样返回线程句柄。如果任何操作失败了，便返回NULL。</p>
<p>5) _endthreadex的一些要点：</p>
<p>&#8226;C运行期库的_getptd函数内部调用操作系统的TlsGetValue函数，该函数负责检索调用线程的tiddata内存块的地址。</p>
<p>&#8226;然后该数据块被释放，而操作系统的ExitThread函数被调用，以便真正撤消该线程。当然，退出代码要正确地设置和传递。</p>
<p>6) 虽然也提供了简化版的的_beginthread和_endthread，但是可控制性太差，所以一般不使用。</p>
<p>6）线程handle因为是内核对象，所以需要在最后close handle。</p>
<p>7）C++主线程的终止，同时也会终止所有主线程创建的子线程，不管子线程有没有执行完毕。</p>
<p>8）如果某线程挂起，然后有调用WaitForSingleObject等待该线程，就会导致死锁。</p>
<p>二 线程同步之Critical Sections</p>
<p>1） 因为Critical Sections不是内核对象，所以只能用来同一进程内线程间的同步，不能用来多个不同进程间的线程的同步。</p>
<p>2） 如果在Critical Sections中间突然程序crash或是exit而没有调用LeaveCriticalSection，则结果是该线程所对应的内核不能被释放，该线程成为死线程。</p>
<p>3） 要比其他的内核对象的速度要快。</p>
<p>4）很好的封装：</p>
<p>class CritSect<br>{<br>public:<br>&nbsp;&nbsp;&nbsp; friend class Lock;<br>&nbsp;&nbsp;&nbsp; CritSect() { InitializeCriticalSection(&amp;_critSection); }<br>&nbsp;&nbsp;&nbsp; ~CritSect() { DeleteCriticalSection(&amp;_critSection); }<br>private:<br>&nbsp;&nbsp;&nbsp; void Acquire(){EnterCriticalSection(&amp;_critSection);}<br>&nbsp;&nbsp;&nbsp; void Release(){LeaveCriticalSection(&amp;_critSection);}</p>
<p>&nbsp;&nbsp;&nbsp; CRITICAL_SECTION _critSection;<br>};</p>
<p>class Lock<br>{<br>public:<br>&nbsp;&nbsp;&nbsp;&nbsp; Lock(CritSect&amp; critSect):_critSect(critSect) {&nbsp;&nbsp;&nbsp; _critSect.Acquire(); }<br>&nbsp;&nbsp;&nbsp;&nbsp; ~Lock(){_critSect.Release();}<br>private:<br>&nbsp;&nbsp;&nbsp; CritSect&amp; _critSect;<br>};<br>调用：CritSect sect;Lock lock(sect);</p>
<p>三 线程同步之Mutex<br>&nbsp;&nbsp;&nbsp; <br>1）互斥对象（mutex）内核对象能够确保线程拥有对单个资源的互斥访问权。实际上互斥对象是因此而得名的。互斥对象包含一个使用数量，一个线程ID和一个递归计数器。<br>&nbsp;2） 互斥对象的行为特性与关键代码段相同，但是互斥对象属于内核对象，而关键代码段则属于用户方式对象。这意味着互斥对象的运行速度比关键代码段要慢。但是这也意味着不同进程中的多个线程能够访问单个互斥对象，并且这意味着线程在等待访问资源时可以设定一个超时值。</p>
<p>&nbsp;3） ID用于标识系统中的哪个线程当前拥有互斥对象，递归计数器用于指明该线程拥有互斥对象的次数。</p>
<p>&nbsp;4） 互斥对象有许多用途，属于最常用的内核对象之一。通常来说，它们用于保护由多个线程访问的内存块。如果多个线程要同时访问内存块，内存块中的数据就可能遭到破坏。互斥对象能够保证访问内存块的任何线程拥有对该内存块的独占访问权，这样就能够保证数据的完整性。</p>
<p>5）互斥对象的使用规则如下：</p>
<p>&#8226; 如果线程ID是0（这是个无效ID），互斥对象不被任何线程所拥有，并且发出该互斥对象的通知信号。</p>
<p>&#8226; 如果ID是个非0数字，那么一个线程就拥有互斥对象，并且不发出该互斥对象的通知信号。</p>
<p>&#8226; 与所有其他内核对象不同， 互斥对象在操作系统中拥有特殊的代码，允许它们违反正常的规则。</p>
<p><br>四 线程同步之Event</p>
<p>1）在所有的内核对象中，事件内核对象是个最基本的对象。它们包含一个使用计数（与所有内核对象一样），一个用于指明该事件是个自动重置的事件还是一个人工重置的事件的布尔值，另一个用于指明该事件处于已通知状态还是未通知状态的布尔值。 </p>
<p>2）事件能够通知一个操作已经完成。有两种不同类型的事件对象。一种是人工重置的事件，另一种是自动重置的事件。当人工重置的事件得到通知时，等待该事件的所有线程均变为可调度线程。当一个自动重置的事件得到通知时，等待该事件的线程中只有一个线程变为可调度线程。 </p>
<p>3）当一个线程执行初始化操作，然后通知另一个线程执行剩余的操作时，事件使用得最多。事件初始化为未通知状态，然后，当该线程完成它的初始化操作后，它就将事件设置为已通知状态。这时，一直在等待该事件的另一个线程发现该事件已经得到通知，因此它就变成可调度线程。</p>
<p>&nbsp;4）Microsoft为自动重置的事件定义了应该成功等待的副作用规则，即当线程成功地等待到该对象时，自动重置的事件就会自动重置到未通知状态。这就是自动重置的事件如何获得它们的名字的方法。通常没有必要为自动重置的事件调用ResetEvent函数，因为系统会自动对事件进行重置。但是，Microsoft没有为人工重置的事件定义成功等待的副作用，所以需要调用ResetEvent()。</p>
<p>五 线程同步之其他</p>
<p>1）线程局部存储 （TLS），同一进程中的所有线程共享相同的虚拟地址空间。不同的线程中的局部变量有不同的副本，但是static和globl变量是同一进程中的所有线程共享的。使用TLS技术可以为static和globl的变量，根据当前进程的线程数量创建一个array，每个线程可以通过array的index来访问对应的变量，这样也就保证了static和global的变量为每一个线程都创建不同的副本。</p>
<p>2）互锁函数的家族十分的庞大，例如InterlockedExchangeAdd（）。。。，使用互锁函数的优点是：他的速度要比其他的CriticalSection,Mutex,Event,Semaphore快很多。</p>
<p>3）等待函数，例如WaitForSingleObject 函数用来检测 hHandle 事件的信号状态，当函数的执行时间超过 dwMilliseconds 就返回，但如果参数 dwMilliseconds 为 INFINITE 时函数将直到相应时间事件变成有信号状态才返回，否则就一直等待下去，直到 WaitForSingleObject 有返回直才执行后面的代码。</p>
<p>六 《Windows核心编程（英文版&#183;第5版）》<br>最好的windows多线程编程参考，更多更详细请看原书。</p><img src ="http://www.cppblog.com/mzty/aggbug/57470.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mzty/" target="_blank">梦在天涯</a> 2008-07-29 22:54 <a href="http://www.cppblog.com/mzty/archive/2008/07/29/57470.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>dynamic_cast使用的讨论</title><link>http://www.cppblog.com/mzty/archive/2008/02/19/42929.html</link><dc:creator>梦在天涯</dc:creator><author>梦在天涯</author><pubDate>Tue, 19 Feb 2008 02:08:00 GMT</pubDate><guid>http://www.cppblog.com/mzty/archive/2008/02/19/42929.html</guid><wfw:comment>http://www.cppblog.com/mzty/comments/42929.html</wfw:comment><comments>http://www.cppblog.com/mzty/archive/2008/02/19/42929.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.cppblog.com/mzty/comments/commentRss/42929.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mzty/services/trackbacks/42929.html</trackback:ping><description><![CDATA[<br>一 问题<br>1）什么时候应必须使用dynamic_cast<br>2）什么时候dynamic_cast可以使用static_cast代替<br><br>二 实例<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: #008000">//</span><span style="COLOR: #008000">&nbsp;TestCast.cpp&nbsp;:&nbsp;Defines&nbsp;the&nbsp;entry&nbsp;point&nbsp;for&nbsp;the&nbsp;console&nbsp;application.<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #008000">//<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>#include&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">stdafx.h</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>#include&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">iostream</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">using</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">namespace</span><span style="COLOR: #000000">&nbsp;std;<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><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">&nbsp;Base<br><img id=Codehighlighter1_148_291_Open_Image onclick="this.style.display='none'; Codehighlighter1_148_291_Open_Text.style.display='none'; Codehighlighter1_148_291_Closed_Image.style.display='inline'; Codehighlighter1_148_291_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_148_291_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_148_291_Closed_Text.style.display='none'; Codehighlighter1_148_291_Open_Image.style.display='inline'; Codehighlighter1_148_291_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top></span><span id=Codehighlighter1_148_291_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_148_291_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;</span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">:<br><img id=Codehighlighter1_180_209_Open_Image onclick="this.style.display='none'; Codehighlighter1_180_209_Open_Text.style.display='none'; Codehighlighter1_180_209_Closed_Image.style.display='inline'; Codehighlighter1_180_209_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_180_209_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_180_209_Closed_Text.style.display='none'; Codehighlighter1_180_209_Open_Image.style.display='inline'; Codehighlighter1_180_209_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">virtual</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;f()&nbsp;</span><span id=Codehighlighter1_180_209_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_180_209_Open_Text><span style="COLOR: #000000">{&nbsp;cout&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">Base::f</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;endl;&nbsp;}</span></span><span style="COLOR: #000000"><br><img id=Codehighlighter1_224_252_Open_Image onclick="this.style.display='none'; Codehighlighter1_224_252_Open_Text.style.display='none'; Codehighlighter1_224_252_Closed_Image.style.display='inline'; Codehighlighter1_224_252_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_224_252_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_224_252_Closed_Text.style.display='none'; Codehighlighter1_224_252_Open_Image.style.display='inline'; Codehighlighter1_224_252_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;f1()</span><span id=Codehighlighter1_224_252_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_224_252_Open_Text><span style="COLOR: #000000">{cout&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">Base::f1</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;endl;}</span></span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top></span><span style="COLOR: #0000ff">private</span><span style="COLOR: #000000">:<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">double</span><span style="COLOR: #000000">&nbsp;x;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">double</span><span style="COLOR: #000000">&nbsp;y;<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></span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">&nbsp;Derived&nbsp;:&nbsp;</span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">&nbsp;Base<br><img id=Codehighlighter1_322_461_Open_Image onclick="this.style.display='none'; Codehighlighter1_322_461_Open_Text.style.display='none'; Codehighlighter1_322_461_Closed_Image.style.display='inline'; Codehighlighter1_322_461_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_322_461_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_322_461_Closed_Text.style.display='none'; Codehighlighter1_322_461_Open_Image.style.display='inline'; Codehighlighter1_322_461_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top></span><span id=Codehighlighter1_322_461_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_322_461_Open_Text><span style="COLOR: #000000">{<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_352_383_Open_Image onclick="this.style.display='none'; Codehighlighter1_352_383_Open_Text.style.display='none'; Codehighlighter1_352_383_Closed_Image.style.display='inline'; Codehighlighter1_352_383_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_352_383_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_352_383_Closed_Text.style.display='none'; Codehighlighter1_352_383_Open_Image.style.display='inline'; Codehighlighter1_352_383_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">virtual</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;f()</span><span id=Codehighlighter1_352_383_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_352_383_Open_Text><span style="COLOR: #000000">{cout&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">Derived::f</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;endl;&nbsp;}</span></span><span style="COLOR: #000000"><br><img id=Codehighlighter1_405_436_Open_Image onclick="this.style.display='none'; Codehighlighter1_405_436_Open_Text.style.display='none'; Codehighlighter1_405_436_Closed_Image.style.display='inline'; Codehighlighter1_405_436_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_405_436_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_405_436_Closed_Text.style.display='none'; Codehighlighter1_405_436_Open_Image.style.display='inline'; Codehighlighter1_405_436_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">virtual</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;k()</span><span id=Codehighlighter1_405_436_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_405_436_Open_Text><span style="COLOR: #000000">{cout&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">Derived::k</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;endl;&nbsp;}</span></span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top></span><span style="COLOR: #0000ff">private</span><span style="COLOR: #000000">:<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">double</span><span style="COLOR: #000000">&nbsp;z;<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><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">&nbsp;Base1<br><img id=Codehighlighter1_477_582_Open_Image onclick="this.style.display='none'; Codehighlighter1_477_582_Open_Text.style.display='none'; Codehighlighter1_477_582_Closed_Image.style.display='inline'; Codehighlighter1_477_582_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_477_582_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_477_582_Closed_Text.style.display='none'; Codehighlighter1_477_582_Open_Image.style.display='inline'; Codehighlighter1_477_582_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top></span><span id=Codehighlighter1_477_582_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_477_582_Open_Text><span style="COLOR: #000000">{<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_507_536_Open_Image onclick="this.style.display='none'; Codehighlighter1_507_536_Open_Text.style.display='none'; Codehighlighter1_507_536_Closed_Image.style.display='inline'; Codehighlighter1_507_536_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_507_536_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_507_536_Closed_Text.style.display='none'; Codehighlighter1_507_536_Open_Image.style.display='inline'; Codehighlighter1_507_536_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">virtual</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;g()</span><span id=Codehighlighter1_507_536_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_507_536_Open_Text><span style="COLOR: #000000">{&nbsp;cout&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">Base1::g</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;endl;}</span></span><span style="COLOR: #000000"><br><img id=Codehighlighter1_551_580_Open_Image onclick="this.style.display='none'; Codehighlighter1_551_580_Open_Text.style.display='none'; Codehighlighter1_551_580_Closed_Image.style.display='inline'; Codehighlighter1_551_580_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_551_580_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_551_580_Closed_Text.style.display='none'; Codehighlighter1_551_580_Open_Image.style.display='inline'; Codehighlighter1_551_580_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;g1()</span><span id=Codehighlighter1_551_580_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_551_580_Open_Text><span style="COLOR: #000000">{cout&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">Base1::g1</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;endl;}</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></span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">&nbsp;Derived1&nbsp;:&nbsp;</span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">&nbsp;Base,</span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">&nbsp;Base1<br><img id=Codehighlighter1_627_745_Open_Image onclick="this.style.display='none'; Codehighlighter1_627_745_Open_Text.style.display='none'; Codehighlighter1_627_745_Closed_Image.style.display='inline'; Codehighlighter1_627_745_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_627_745_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_627_745_Closed_Text.style.display='none'; Codehighlighter1_627_745_Open_Image.style.display='inline'; Codehighlighter1_627_745_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top></span><span id=Codehighlighter1_627_745_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_627_745_Open_Text><span style="COLOR: #000000">{<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_657_689_Open_Image onclick="this.style.display='none'; Codehighlighter1_657_689_Open_Text.style.display='none'; Codehighlighter1_657_689_Closed_Image.style.display='inline'; Codehighlighter1_657_689_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_657_689_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_657_689_Closed_Text.style.display='none'; Codehighlighter1_657_689_Open_Image.style.display='inline'; Codehighlighter1_657_689_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">virtual</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;f()</span><span id=Codehighlighter1_657_689_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_657_689_Open_Text><span style="COLOR: #000000">{&nbsp;cout&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">Derived1::f</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;endl;}</span></span><span style="COLOR: #000000"><br><img id=Codehighlighter1_711_743_Open_Image onclick="this.style.display='none'; Codehighlighter1_711_743_Open_Text.style.display='none'; Codehighlighter1_711_743_Closed_Image.style.display='inline'; Codehighlighter1_711_743_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_711_743_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_711_743_Closed_Text.style.display='none'; Codehighlighter1_711_743_Open_Image.style.display='inline'; Codehighlighter1_711_743_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">virtual</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;h()</span><span id=Codehighlighter1_711_743_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_711_743_Open_Text><span style="COLOR: #000000">{&nbsp;cout&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">Derived1::h</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;endl;}</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><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;Test1()<br><img id=Codehighlighter1_762_1407_Open_Image onclick="this.style.display='none'; Codehighlighter1_762_1407_Open_Text.style.display='none'; Codehighlighter1_762_1407_Closed_Image.style.display='inline'; Codehighlighter1_762_1407_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_762_1407_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_762_1407_Closed_Text.style.display='none'; Codehighlighter1_762_1407_Open_Image.style.display='inline'; Codehighlighter1_762_1407_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top></span><span id=Codehighlighter1_762_1407_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_762_1407_Open_Text><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>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;对于单继承，<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;如果PD真的指向Derived，用dynamic_cast和static_cast效果相同</span><span style="COLOR: #008000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;Base&nbsp;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">pD&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000">&nbsp;Derived;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;Derived&nbsp;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">pD1&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;dynamic_cast</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">Derived</span><span style="COLOR: #000000">*&gt;</span><span style="COLOR: #000000">(pD);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;pD1</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">f();<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;pD1</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">k();<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;pD1</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">f1();<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>&nbsp;&nbsp;&nbsp;&nbsp;Derived&nbsp;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">pD2&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;static_cast</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">Derived</span><span style="COLOR: #000000">*&gt;</span><span style="COLOR: #000000">(pD);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;pD2</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">f();<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;pD2</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">k();<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;pD2</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">f1();<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><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;但是如果PB不是真的指向Derived，则用dynamic_cast则返回NULL，能够更早的禁止error的发生，<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;如果用static_cast虽然返回的不为NULL，但是运行时可能抛出exception。</span><span style="COLOR: #008000"><br><img id=Codehighlighter1_1165_1181_Open_Image onclick="this.style.display='none'; Codehighlighter1_1165_1181_Open_Text.style.display='none'; Codehighlighter1_1165_1181_Closed_Image.style.display='inline'; Codehighlighter1_1165_1181_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_1165_1181_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_1165_1181_Closed_Text.style.display='none'; Codehighlighter1_1165_1181_Open_Image.style.display='inline'; Codehighlighter1_1165_1181_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span id=Codehighlighter1_1165_1181_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">/**/</span><span id=Codehighlighter1_1165_1181_Open_Text><span style="COLOR: #808080">///</span><span style="COLOR: #008000">/&nbsp;Error&nbsp;code&nbsp;</span><span style="COLOR: #808080"></span></span><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">Base&nbsp;*pB&nbsp;=&nbsp;new&nbsp;Base();<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">Derived&nbsp;*pD3&nbsp;=&nbsp;static_cast&lt;Derived*&gt;(pB);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">pD3-&gt;f();<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">pD3-&gt;k();<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">pD3-&gt;f1();<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>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">Derived&nbsp;*pD4&nbsp;=&nbsp;dynamic_cast&lt;Derived*&gt;(pB);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">pD4-&gt;f();<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">pD4-&gt;k();<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">pD4-&gt;f1();</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><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><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;Test2()<br><img id=Codehighlighter1_1423_2017_Open_Image onclick="this.style.display='none'; Codehighlighter1_1423_2017_Open_Text.style.display='none'; Codehighlighter1_1423_2017_Closed_Image.style.display='inline'; Codehighlighter1_1423_2017_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_1423_2017_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_1423_2017_Closed_Text.style.display='none'; Codehighlighter1_1423_2017_Open_Image.style.display='inline'; Codehighlighter1_1423_2017_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top></span><span id=Codehighlighter1_1423_2017_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_1423_2017_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;对于多重继承，<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;如果PD真的指向的是Derived1，使用dynamic_cast和static_cast都可以转化为Derived1，<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;但是如果要转化为Base的兄弟类Base1，必须使用dynamic_cast，使用static_cast不能编译。</span><span style="COLOR: #008000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;Base&nbsp;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">pD&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000">&nbsp;Derived1;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;Derived1&nbsp;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">pD1&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;dynamic_cast</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">Derived1</span><span style="COLOR: #000000">*&gt;</span><span style="COLOR: #000000">(pD);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;pD1</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">f();<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;pD1</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">h();<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;pD1</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">f1();<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>&nbsp;&nbsp;&nbsp;&nbsp;Base1&nbsp;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">pB1&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;dynamic_cast</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">Base1</span><span style="COLOR: #000000">*&gt;</span><span style="COLOR: #000000">(pD);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;pB1</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">g();<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>&nbsp;&nbsp;&nbsp;&nbsp;Derived1&nbsp;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">pD2&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;static_cast</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">Derived1</span><span style="COLOR: #000000">*&gt;</span><span style="COLOR: #000000">(pD);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;pD2</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">f();<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;pD1</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">h();<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;pD2</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">f1();<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top><br><img id=Codehighlighter1_1849_1876_Open_Image onclick="this.style.display='none'; Codehighlighter1_1849_1876_Open_Text.style.display='none'; Codehighlighter1_1849_1876_Closed_Image.style.display='inline'; Codehighlighter1_1849_1876_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_1849_1876_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_1849_1876_Closed_Text.style.display='none'; Codehighlighter1_1849_1876_Open_Image.style.display='inline'; Codehighlighter1_1849_1876_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span id=Codehighlighter1_1849_1876_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">/**/</span><span id=Codehighlighter1_1849_1876_Open_Text><span style="COLOR: #808080">///</span><span style="COLOR: #008000">/&nbsp;error&nbsp;can&nbsp;not&nbsp;compiler</span><span style="COLOR: #808080"></span></span><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">Base1&nbsp;*pB2&nbsp;=&nbsp;static_cast&lt;Base1*&gt;(pD);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">pB2-&gt;g();<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>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;当然对于PB不是真的指向Derived1，想要转化为Derived1或Base的兄弟类Base1，情况与Test1中的error情况相同。</span><span style="COLOR: #008000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top></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/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><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;_tmain(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;argc,&nbsp;_TCHAR</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;argv[])<br><img id=Codehighlighter1_2057_2098_Open_Image onclick="this.style.display='none'; Codehighlighter1_2057_2098_Open_Text.style.display='none'; Codehighlighter1_2057_2098_Closed_Image.style.display='inline'; Codehighlighter1_2057_2098_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_2057_2098_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_2057_2098_Closed_Text.style.display='none'; Codehighlighter1_2057_2098_Open_Image.style.display='inline'; Codehighlighter1_2057_2098_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top></span><span id=Codehighlighter1_2057_2098_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_2057_2098_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;Test1();<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>&nbsp;&nbsp;&nbsp;&nbsp;Test2();<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>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0</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>
<br>三 结论<br><br>大家先总结下，哈哈！<img src ="http://www.cppblog.com/mzty/aggbug/42929.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mzty/" target="_blank">梦在天涯</a> 2008-02-19 10:08 <a href="http://www.cppblog.com/mzty/archive/2008/02/19/42929.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C++ 虚函数表解析（转）</title><link>http://www.cppblog.com/mzty/archive/2008/02/18/42877.html</link><dc:creator>梦在天涯</dc:creator><author>梦在天涯</author><pubDate>Mon, 18 Feb 2008 05:29:00 GMT</pubDate><guid>http://www.cppblog.com/mzty/archive/2008/02/18/42877.html</guid><wfw:comment>http://www.cppblog.com/mzty/comments/42877.html</wfw:comment><comments>http://www.cppblog.com/mzty/archive/2008/02/18/42877.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/mzty/comments/commentRss/42877.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mzty/services/trackbacks/42877.html</trackback:ping><description><![CDATA[<p align=center><strong><span twffan="done">C++ <span twffan="done">虚函数表解析</span></span></strong></p>
<p align=center><font face="Times New Roman" size=3></font>&nbsp;</p>
<h1><span twffan="done"><font size=5>前言</font></span><font face="Times New Roman" size=3>&nbsp;</font></h1>
<p><font size=3><font face="Times New Roman">C++</font><span twffan="done">中的虚函数的作用主要是实现了多态的机制。关于多态，简而言之就是用父类型别的指针指向其子类的实例，然后通过父类的指针调用实际子类的成员函数。这种技术可以让父类的指针有&#8220;多种形态&#8221;，这是一种泛型技术。所谓泛型技术，说白了就是试图使用不变的代码来实现可变的算法。比如：模板技术，</span><font face="Times New Roman">RTTI</font><span twffan="done">技术，虚函数技术，要么是试图做到在编译时决议，要么试图做到运行时决议。</span></font><font face="Times New Roman" size=3>&nbsp;</font></p>
<p><font size=3><span twffan="done">关于虚函数的使用方法，我在这里不做过多的阐述。大家可以看看相关的</span><font face="Times New Roman">C++</font><span twffan="done">的书籍。在这篇文章中，我只想从虚函数的实现机制上面为大家</span><span twffan="done"><font face="Times New Roman"> </font></span><span twffan="done">一个清晰的剖析。</span></font><font face="Times New Roman" size=3>&nbsp;</font></p>
<p><span twffan="done"><font size=3>当然，相同的文章在网上也出现过一些了，但我总感觉这些文章不是很容易阅读，大段大段的代码，没有图片，没有详细的说明，没有比较，没有举一反三。不利于学习和阅读，所以这是我想写下这篇文章的原因。也希望大家多给我提意见。</font></span><font face="Times New Roman" size=3>&nbsp;</font></p>
<p><span twffan="done"><font size=3>言归正传，让我们一起进入虚函数的世界。</font></span><font face="Times New Roman" size=3>&nbsp;</font></p>
<p><font face="Times New Roman" size=3>&nbsp;</font></p>
<h1><span twffan="done"><font size=5>虚函数表</font></span><font face="Times New Roman" size=3>&nbsp;</font></h1>
<p><font size=3><span twffan="done">对</span><font face="Times New Roman">C++ </font><span twffan="done">了解的人都应该知道虚函数（</span><font face="Times New Roman">Virtual Function</font><span twffan="done">）是通过一张虚函数表（</span><font face="Times New Roman">Virtual Table</font><span twffan="done">）来实现的。简称为</span><font face="Times New Roman">V-Table</font><span twffan="done">。在这个表中，主是要一个类的虚函数的地址表，这张表解决了继承、重载的问题，保证其容真实反应实际的函数。这样，在有虚函数的类的实例中这个表被分配在了这个实例的内存中，所以，当我们用父类的指针来操作一个子类的时候，这张虚函数表就显得由为重要了，它就像一个地图一样，指明了实际所应该调用的函数。</span></font><font face="Times New Roman" size=3>&nbsp;</font></p>
<p><font size=3><span twffan="done">这里我们着重看一下这张虚函数表。在</span><font face="Times New Roman">C++</font><span twffan="done">的标准规格说明书中说到，编译器必需要保证虚函数表的指针存在于对象实例中最前面的位置（这是为了保证正确取到虚函数的偏移量）。</span><span twffan="done"><font face="Times New Roman"> </font></span><span twffan="done">这意味着我们通过对象实例的地址得到这张虚函数表，然后就可以遍历其中函数指针，并调用相应的函数。</span></font><font face="Times New Roman" size=3>&nbsp;</font></p>
<p><font size=3><span twffan="done">听我扯了那么多，我可以感觉出来你现在可能比以前更加晕头转向了。</span><span twffan="done"><font face="Times New Roman"> </font></span><span twffan="done">没关系，下面就是实际的例子，相信聪明的你一看就明白了。</span></font><font face="Times New Roman" size=3>&nbsp;</font></p>
<p><span twffan="done"><font size=3>假设我们有这样的一个类：</font></span></p>
<p><font face="Times New Roman" size=3>&nbsp;</font></p>
<p><span twffan="done">class</span><span twffan="done"> Base {</span></p>
<p><span twffan="done"><span twffan="done">&nbsp;&nbsp;&nbsp;&nbsp; </span>public</span><span twffan="done">:</span></p>
<p><span twffan="done"><span twffan="done">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span twffan="done">virtual</span> <span twffan="done">void</span> f() { cout &lt;&lt; <span twffan="done">"Base::f"</span> &lt;&lt; endl; }</span></p>
<p><span twffan="done"><span twffan="done">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span twffan="done">virtual</span> <span twffan="done">void</span> g() { cout &lt;&lt; <span twffan="done">"Base::g"</span> &lt;&lt; endl; }</span></p>
<p><span twffan="done"><span twffan="done">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span twffan="done">virtual</span> <span twffan="done">void</span> h() { cout &lt;&lt; <span twffan="done">"Base::h"</span> &lt;&lt; endl; }</span>&nbsp;</p>
<p><span twffan="done">};</span></p>
<p><font face="Times New Roman" size=3>&nbsp;</font></p>
<p><font size=3><span twffan="done">按照上面的说法，我们可以通过</span><font face="Times New Roman">Base</font><span twffan="done">的实例来得到虚函数表。</span><span twffan="done"><font face="Times New Roman"> </font></span><span twffan="done">下面是实际例程：</span></font></p>
<p><font face="Times New Roman" size=3>&nbsp;</font></p>
<p><span twffan="done"><span twffan="done"><font size=3>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font></span></span><span twffan="done">typedef</span><span twffan="done"> <span twffan="done">void</span>(*Fun)(<span twffan="done">void</span>);</span><span twffan="done"><font size=3>&nbsp;</font></span></p>
<p><span twffan="done"><span twffan="done">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>Base b;</span>&nbsp;</p>
<p><span twffan="done"><span twffan="done">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>Fun pFun = NULL;</span>&nbsp;</p>
<p><span twffan="done"><span twffan="done">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>cout &lt;&lt; <span twffan="done">"</span></span><span twffan="done">虚函数表地址：</span><span twffan="done">"</span><span twffan="done"> &lt;&lt; (<span twffan="done">int</span>*)(&amp;b) &lt;&lt; endl;</span></p>
<p><span twffan="done"><span twffan="done">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>cout &lt;&lt; <span twffan="done">"</span></span><span twffan="done">虚函数表</span><span twffan="done"> — </span><span twffan="done">第一个函数地址：</span><span twffan="done">"</span><span twffan="done"> &lt;&lt; (<span twffan="done">int</span>*)*(<span twffan="done">int</span>*)(&amp;b) &lt;&lt; endl;<br></span>&nbsp;</p>
<p><span twffan="done"><span twffan="done">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span twffan="done">// Invoke the first virtual function&nbsp;</span></span></p>
<p><span twffan="done"><span twffan="done">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>pFun = (Fun)*((<span twffan="done">int</span>*)*(<span twffan="done">int</span>*)(&amp;b));</span></p>
<p><span twffan="done"><span twffan="done">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>pFun();</span></p>
<p><font face="Times New Roman" size=3>&nbsp;</font></p>
<p><font size=3><span twffan="done">实际运行经果如下：</span><font face="Times New Roman">(Windows XP+VS2003,&nbsp;Linux 2.6.22 + GCC 4.1.3)</font></font></p>
<p><font face="Times New Roman" size=3>&nbsp;</font></p>
<p><span twffan="done">虚函数表地址：</span><span twffan="done">0012FED4</span></p>
<p><span twffan="done">虚函数表</span><span twffan="done"> — </span><span twffan="done">第一个函数地址：</span><span twffan="done">0044F148</span></p>
<p><span twffan="done">Base::f</span>&nbsp;</p>
<p><font size=3><span twffan="done">通过这个示例，我们可以看到，我们可以通过强行把</span><font face="Times New Roman">&amp;b</font><span twffan="done">转成</span><font face="Times New Roman">int *</font><span twffan="done">，取得虚函数表的地址，然后，再次取址就可以得到第一个虚函数的地址了，也就是</span><font face="Times New Roman">Base::f()</font><span twffan="done">，这在上面的程序中得到了验证（把</span><font face="Times New Roman">int* </font><span twffan="done">强制转成了函数指针）。通过这个示例，我们就可以知道如果要调用</span><font face="Times New Roman">Base::g()</font><span twffan="done">和</span><font face="Times New Roman">Base::h()</font><span twffan="done">，其代码如下：</span></font></p>
<p><font face="Times New Roman" size=3>&nbsp;</font></p>
<p><span twffan="done"><font face="Times New Roman" size=3>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font></span><span twffan="done">(Fun)*((<span twffan="done">int</span>*)*(<span twffan="done">int</span>*)(&amp;b)+0);&nbsp;<span twffan="done">// Base::f()</span></span></p>
<p><span twffan="done"><span twffan="done">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>(Fun)*((<span twffan="done">int</span>*)*(<span twffan="done">int</span>*)(&amp;b)+1);&nbsp;<span twffan="done">// Base::g()</span></span></p>
<p><span twffan="done"><span twffan="done">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>(Fun)*((<span twffan="done">int</span>*)*(<span twffan="done">int</span>*)(&amp;b)+2);&nbsp;<span twffan="done">// Base::h()</span></span></p>
<p>&nbsp;</p>
<p><span twffan="done"><font size=3>这个时候你应该懂了吧。什么？还是有点晕。也是，这样的代码看着太乱了。没问题，让我画个图解释一下。如下所示：</font></span></p>
<p><span twffan="done"><font size=3></font></span></p>
<p align=center><span twffan="done"><font size=3><img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/haoel/15190/o_vtable1.jpg" twffan="done"></font></span></p>
<p><span twffan="done"><font size=3></font></span></p>
<p align=center><font size=3></font></p>
<p><font size=3><span twffan="done">注意：在上面这个图中，我在虚函数表的最后多加了一个结点，这是虚函数表的结束结点，就像字符串的结束符&#8220;</span><font face="Times New Roman">\0</font><span twffan="done">&#8221;一样，其标志了虚函数表的结束。这个结束标志的值在不同的编译器下是不同的。在</span><font face="Times New Roman">WinXP+VS2003</font><span twffan="done">下，这个值是</span><font face="Times New Roman">NULL</font><span twffan="done">。而在</span><font face="Times New Roman">Ubuntu 7.10 + Linux 2.6.22 + GCC 4.1.3</font><span twffan="done">下，这个值是如果</span><font face="Times New Roman">1</font><span twffan="done">，表示还有下一个虚函数表，如果值是</span><font face="Times New Roman">0</font><span twffan="done">，表示是最后一个虚函数表。</span></font></p>
<p><font face="Times New Roman" size=3>&nbsp;</font></p>
<p><font face="Times New Roman" size=3>&nbsp;</font></p>
<p><span twffan="done"><font size=3>下面，我将分别说明&#8220;无重载&#8221;和&#8220;有重载&#8221;时的虚函数表的样子。没有重载父类的虚函数是毫无意义的。我之所以要讲述没有重载的情况，主要目的是为了给一个对比。在比较之下，我们可以更加清楚地知道其内部的具体实现。</font></span></p>
<p><font face="Times New Roman" size=3>&nbsp;</font></p>
<h1><span twffan="done"><font size=5>一般继承（无虚函数重载）</font></span></h1>
<p><font face="Times New Roman" size=3>&nbsp;</font></p>
<p><span twffan="done"><font size=3>下面，再让我们来看看继承时的虚函数表是什么样的。假设有如下所示的一个继承关系：</font></span></p>
<p><font face="Times New Roman" size=3>&nbsp;</font></p>
<p align=center><img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/haoel/15190/o_Drawing3.jpg" twffan="done"></p>
<p align=center><font face="Times New Roman" size=3></font></p>
<p><font face="Times New Roman" size=3>&nbsp;</font></p>
<p><span twffan="done"><font size=3>请注意，在这个继承关系中，子类没有重载任何父类的函数。那么，在派生类的实例中，其虚函数表如下所示：</font></span></p>
<p><span twffan="done"><font size=3></font></span></p>
<p align=center></p>
<p><font face="Times New Roman" size=3>&nbsp;</font></p>
<p><font size=3><span twffan="done">对于实例：</span><font face="Times New Roman">Derive d; </font><span twffan="done">的虚函数表如下：</span></font></p>
<p><font size=3></font></p>
<p align=center><font size=3><span twffan="done"><span twffan="done"><img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/haoel/15190/o_vtable2.JPG" twffan="done"></span></span></font></p>
<p align=center><font size=3></font></p>
<p><font face="Times New Roman" size=3>&nbsp;</font></p>
<p><span twffan="done"><font size=3>我们可以看到下面几点：</font></span></p>
<p><font size=3><span twffan="done"><span twffan="done"><font face="Times New Roman">1）</font></span></span><span twffan="done">虚函数按照其声明顺序放于表中。</span></font></p>
<p><font size=3><span twffan="done"><span twffan="done"><font face="Times New Roman">2）</font></span></span><span twffan="done">父类的虚函数在子类的虚函数前面。</span></font></p>
<p><font face="Times New Roman" size=3>&nbsp;</font></p>
<p><span twffan="done"><font size=3>我相信聪明的你一定可以参考前面的那个程序，来编写一段程序来验证。</font></span><font face="Times New Roman" size=3>&nbsp;</font></p>
<p><font face="Times New Roman" size=3>&nbsp;</font></p>
<h1><span twffan="done"><font size=5>一般继承（有虚函数重载）</font></span></h1>
<p><font face="Times New Roman" size=3>&nbsp;</font></p>
<p><span twffan="done"><font size=3>重载父类的虚函数是很显然的事情，不然，虚函数就变得毫无意义。下面，我们来看一下，如果子类中有虚函数重载了父类的虚函数，会是一个什么样子？假设，我们有下面这样的一个继承关系。</font></span></p>
<p><font face="Times New Roman" size=3>&nbsp;</font></p>
<p align=center><font face="Times New Roman" size=3>&nbsp;<img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/haoel/15190/o_Drawing4.jpg" twffan="done"></font></p>
<p align=center><font face="Times New Roman" size=3></font></p>
<p align=center><font face="Times New Roman" size=3>&nbsp;</font></p>
<p><font size=3><span twffan="done">为了让大家看到被继承过后的效果，在这个类的设计中，我只重载了父类的一个函数：</span><font face="Times New Roman">f()</font><span twffan="done">。那么，对于派生类的实例，其虚函数表会是下面的一个样子：</span></font></p>
<p><font face="Times New Roman" size=3>&nbsp;</font></p>
<p align=center><font face="Times New Roman" size=3></font></p>
<p align=center><font face="Times New Roman" size=3><img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/haoel/15190/o_vtable3.JPG" twffan="done"></font></p>
<p>&nbsp;</p>
<p><font face="Times New Roman" size=3></font></p>
<p><span twffan="done"><font size=3>我们从表中可以看到下面几点，</font></span></p>
<p><font size=3><span twffan="done"><span twffan="done"><font face="Times New Roman">1）</font></span></span><span twffan="done">重载的</span><font face="Times New Roman">f()</font><span twffan="done">函数被放到了虚表中原来父类虚函数的位置。</span></font></p>
<p><font size=3><span twffan="done"><span twffan="done"><font face="Times New Roman">2）</font></span></span><span twffan="done">没有被重载的函数依旧。</span></font></p>
<p><font face="Times New Roman" size=3>&nbsp;</font></p>
<p><span twffan="done"><font size=3>这样，我们就可以看到对于下面这样的程序，</font></span></p>
<p><span twffan="done"><font size=3>&nbsp;</font></span></p>
<p><span twffan="done"><span twffan="done">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>Base *b = <span twffan="done">new</span> Derive();</span></p>
<p>&nbsp;</p>
<p><span twffan="done"><span twffan="done">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>b-&gt;f();</span></p>
<p><font face="Times New Roman" size=3>&nbsp;</font></p>
<p><font size=3><span twffan="done">由</span><font face="Times New Roman">b</font><span twffan="done">所指的内存中的虚函数表的</span><font face="Times New Roman">f()</font><span twffan="done">的位置已经被</span><font face="Times New Roman">Derive::f()</font><span twffan="done">函数地址所取代，于是在实际调用发生时，是</span><font face="Times New Roman">Derive::f()</font><span twffan="done">被调用了。这就实现了多态。</span></font><font face="Times New Roman" size=3>&nbsp;</font></p>
<p><font face="Times New Roman" size=3>&nbsp;</font></p>
<h1><span twffan="done"><font size=5>多重继承（无虚函数重载）</font></span><font face="Times New Roman" size=3>&nbsp;</font></h1>
<p><span twffan="done"><font size=3>下面，再让我们来看看多重继承中的情况，假设有下面这样一个类的继承关系。注意：子类并没有重载复类的函数。</font></span></p>
<p><font face="Times New Roman" size=3>&nbsp;</font></p>
<p align=center><font face="Times New Roman" size=3></font></p>
<p align=center><font face="Times New Roman" size=3><img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/haoel/15190/o_Drawing1.jpg" twffan="done">&nbsp;</font></p>
<p align=center><font face="Times New Roman" size=3>&nbsp;</font></p>
<p><span twffan="done"><font size=3>对于子类实例中的虚函数表，是下面这个样子：</font></span></p>
<p><span twffan="done"><font size=3></font></span></p>
<p align=center><span twffan="done"><img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/haoel/15190/o_vtable4.JPG" twffan="done"></span></p>
<p><font face="Times New Roman" size=3>&nbsp;</font></p>
<p align=center><font face="Times New Roman" size=3></font></p>
<p><span twffan="done"><font size=3>我们可以看到：</font></span></p>
<p><span twffan="done"><span twffan="done"><font face="Times New Roman"><font size=3>1）</font>&nbsp;</font></span></span><span twffan="done"><font size=3>每个父类都有自己的虚表。</font></span></p>
<p><span twffan="done"><span twffan="done"><font face="Times New Roman"><font size=3>2）</font>&nbsp;</font></span></span><span twffan="done"><font size=3>子类的成员函数被放到了第一个父类的表中。（所谓的第一个父类是按照声明顺序来判断的）</font></span></p>
<p><font face="Times New Roman" size=3>&nbsp;</font></p>
<p><span twffan="done"><font size=3>这样做就是为了解决不同的父类类型的指针指向同一个子类实例，而能够调用到实际的函数。</font></span></p>
<p><font face="Times New Roman" size=3>&nbsp;</font><font face="Times New Roman" size=3>&nbsp;</font></p>
<h1><span twffan="done"><font size=5>多重继承（有虚函数重载）</font></span></h1>
<p><span twffan="done"><font size=3>下面我们再来看看，如果发生虚函数重载的情况。</font></span></p>
<p><font face="Times New Roman" size=3>&nbsp;</font></p>
<p><font size=3><span twffan="done">下图中，我们重载了父类的</span><font face="Times New Roman">f()</font><span twffan="done">函数。</span></font></p>
<p><font face="Times New Roman" size=3>&nbsp;</font></p>
<p align=center><font face="Times New Roman" size=3></font></p>
<p align=center><font face="Times New Roman" size=3><img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/haoel/15190/o_Drawing2.jpg" twffan="done">&nbsp;</font></p>
<p><font face="Times New Roman" size=3>&nbsp;</font></p>
<p><span twffan="done"><font size=3>下面是对于子类实例中的虚函数表的图：</font></span></p>
<p><font face="Times New Roman" size=3>&nbsp;</font></p>
<p align=center><font face="Times New Roman" size=3></font></p>
<p align=center><font face="Times New Roman" size=3><img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/haoel/15190/o_vtable5.jpg" twffan="done"></font></p>
<p align=center>&nbsp;</p>
<p><font size=3><span twffan="done">我们可以看见，三个父类虚函数表中的</span><font face="Times New Roman">f()</font><span twffan="done">的位置被替换成了子类的函数指针。这样，我们就可以任一静态类型的父类来指向子类，并调用子类的</span><font face="Times New Roman">f()</font><span twffan="done">了。如：</span></font></p>
<p><span twffan="done"><font size=3>&nbsp;</font></span></p>
<p><span twffan="done"><span twffan="done">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>Derive d;</span></p>
<p><span twffan="done"><span twffan="done">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>Base1 *b1 = &amp;d;</span></p>
<p><span twffan="done"><span twffan="done">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>Base2 *b2 = &amp;d;</span></p>
<p><span twffan="done"><span twffan="done">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>Base3 *b3 = &amp;d;</span></p>
<p><span twffan="done"><span twffan="done">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>b1-&gt;f(); <span twffan="done">//Derive::f()</span></span></p>
<p><span twffan="done"><span twffan="done">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>b2-&gt;f(); <span twffan="done">//Derive::f()</span></span></p>
<p><span twffan="done"><span twffan="done">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>b3-&gt;f(); <span twffan="done">//Derive::f()</span></span></p>
<p>&nbsp;</p>
<p><span twffan="done"><span twffan="done">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>b1-&gt;g(); <span twffan="done">//Base1::g()</span></span></p>
<p><span twffan="done"><span twffan="done">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>b2-&gt;g(); <span twffan="done">//Base2::g()</span></span></p>
<p><span twffan="done"><span twffan="done">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>b3-&gt;g(); <span twffan="done">//Base3::g()</span></span></p>
<p><font face="Times New Roman" size=3>&nbsp;</font></p>
<p><font face="Times New Roman" size=3>&nbsp;</font></p>
<h1><span twffan="done"><font size=5>安全性</font></span><font face="Times New Roman" size=3>&nbsp;</font></h1>
<p><font size=3><span twffan="done">每次写</span><font face="Times New Roman">C++</font><span twffan="done">的文章，总免不了要批判一下</span><font face="Times New Roman">C++</font><span twffan="done">。这篇文章也不例外。通过上面的讲述，相信我们对虚函数表有一个比较细致的了解了。水可载舟，亦可覆舟。下面，让我们来看看我们可以用虚函数表来干点什么坏事吧。</span></font></p>
<p><font face="Times New Roman" size=3>&nbsp;</font></p>
<p><strong><font size=3><span twffan="done">一、通过父类型的指针访问子类自己的虚函数</span></font></strong></p>
<p><font size=3><span twffan="done">我们知道，子类没有重载父类的虚函数是一件毫无意义的事情。因为多态也是要基于函数重载的。虽然在上面的图中我们可以看到</span><font face="Times New Roman">Base1</font><span twffan="done">的虚表中有</span><font face="Times New Roman">Derive</font><span twffan="done">的虚函数，但我们根本不可能使用下面的语句来调用子类的自有虚函数：</span></font></p>
<p><span twffan="done"><font size=3>&nbsp;</font></span></p>
<p><span twffan="done"><span twffan="done"><font size=3>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font></span></span><span twffan="done">Base1 *b1 = <span twffan="done">new</span> Derive();</span></p>
<p><span twffan="done"><span twffan="done">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>b1-&gt;f1();&nbsp;</span><span twffan="done">//<span twffan="done">编译出错</span></span></p>
<p><font face="Times New Roman" size=3>&nbsp;</font></p>
<p><font size=3><span twffan="done">任何妄图使用父类指针想调用子类中的<strong>未重载父类的成员函数</strong>的行为都会被编译器视为非法，所以，这样的程序根本无法编译通过。但在运行时，我们可以通过指针的方式访问虚函数表来达到违反</span><font face="Times New Roman">C++</font><span twffan="done">语义的行为。（关于这方面的尝试，通过阅读后面附录的代码，相信你可以做到这一点）</span></font></p>
<p><font face="Times New Roman" size=3>&nbsp;</font></p>
<p><font face="Times New Roman" size=3>&nbsp;</font></p>
<p><font size=3><strong><span twffan="done">二、访问</span><font face="Times New Roman">non-public</font></strong><strong><span twffan="done">的虚函数</span></strong></font></p>
<p><font size=3><span twffan="done">另外，如果父类的虚函数是</span><font face="Times New Roman">private</font><span twffan="done">或是</span><font face="Times New Roman">protected</font><span twffan="done">的，但这些非</span><font face="Times New Roman">public</font><span twffan="done">的虚函数同样会存在于虚函数表中，所以，我们同样可以使用访问虚函数表的方式来访问这些</span><font face="Times New Roman">non-public</font><span twffan="done">的虚函数，这是很容易做到的。</span></font></p>
<p><font face="Times New Roman" size=3>&nbsp;</font></p>
<p><span twffan="done"><font size=3>如：</font></span></p>
<p><font face="Times New Roman" size=3>&nbsp;</font></p>
<p><span twffan="done">class</span><span twffan="done"> Base {</span></p>
<p><span twffan="done"><span twffan="done">&nbsp;&nbsp;&nbsp; </span>private</span><span twffan="done">:</span></p>
<p><span twffan="done"><span twffan="done">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span twffan="done">virtual</span> <span twffan="done">void</span> f() { cout &lt;&lt; <span twffan="done">"Base::f"</span> &lt;&lt; endl; }</span></p>
<p>&nbsp;</p>
<p><span twffan="done">};</span></p>
<p><span twffan="done"><font size=3>&nbsp;</font></span></p>
<p><span twffan="done">class</span><span twffan="done"> Derive : <span twffan="done">public</span> Base{</span></p>
<p>&nbsp;</p>
<p><span twffan="done">};</span></p>
<p>&nbsp;</p>
<p><span twffan="done">typedef</span><span twffan="done"> <span twffan="done">void</span>(*Fun)(<span twffan="done">void</span>);</span></p>
<p>&nbsp;</p>
<p><span twffan="done">void</span><span twffan="done"> main() {</span></p>
<p><span twffan="done"><span twffan="done">&nbsp;&nbsp;&nbsp; </span>Derive d;</span></p>
<p><span twffan="done"><span twffan="done">&nbsp;&nbsp;&nbsp; </span>Fun&nbsp;pFun = (Fun)*((<span twffan="done">int</span>*)*(<span twffan="done">int</span>*)(&amp;d)+<span twffan="done">0</span>);</span></p>
<p><span twffan="done"><span twffan="done">&nbsp;&nbsp;&nbsp; </span>pFun();</span></p>
<p><span twffan="done">}</span></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<h1><span twffan="done"><font size=5>结束语</font></span></h1>
<p><font size=3><font face="Times New Roman">C++</font><span twffan="done">这门语言是一门</span><font face="Times New Roman">Magic</font><span twffan="done">的语言，对于程序员来说，我们似乎永远摸不清楚这门语言背着我们在干了什么。需要熟悉这门语言，我们就必需要了解</span><font face="Times New Roman">C++</font><span twffan="done">里面的那些东西，需要去了解</span><font face="Times New Roman">C++</font><span twffan="done">中那些危险的东西。不然，这是一种搬起石头砸自己脚的编程语言。</span></font></p>
<p><font face="Times New Roman" size=3>&nbsp;</font></p>
<p><font size=3><span twffan="done">在文章束之前还是介绍一下自己吧。我从事软件研发有十个年头了，目前是软件开发技术主管，技术方面，主攻</span><font face="Times New Roman">Unix/C/C++</font><span twffan="done">，比较喜欢网络上的技术，比如分布式计算，网格计算，</span><font face="Times New Roman">P2P</font><span twffan="done">，</span><font face="Times New Roman">Ajax</font><span twffan="done">等一切和互联网相关的东西。管理方面比较擅长于团队建设，技术趋势分析，项目管理。欢迎大家和我交流，我的</span><font face="Times New Roman">MSN</font><span twffan="done">和</span><font face="Times New Roman">Email</font><span twffan="done">是：</span></font><a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#104;&#97;&#111;&#101;&#108;&#64;&#104;&#111;&#116;&#109;&#97;&#105;&#108;&#46;&#99;&#111;&#109;"><font face="Times New Roman" color=#000080 size=3>haoel@hotmail.com</font></a><span twffan="done"><font face="Times New Roman" size=3>&nbsp; </font></span></p>
<p><font face="Times New Roman" size=3>&nbsp;</font></p>
<h1><font size=5><span twffan="done">附录一：</span>VC<span twffan="done">中查看虚函数表</span></font></h1>
<p><font face="Times New Roman" size=3>&nbsp;</font></p>
<p><font size=3><span twffan="done">我们可以在</span><font face="Times New Roman">VC</font><span twffan="done">的</span><font face="Times New Roman">IDE</font><span twffan="done">环境中的</span><font face="Times New Roman">Debug</font><span twffan="done">状态下展开类的实例就可以看到虚函数表了（并不是很完整的）</span></font></p>
<p><font size=3></font></p>
<p align=center><font size=3><span twffan="done"><img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/haoel/15190/o_vtable_vc.JPG" twffan="done"></span></font></p>
<p align=center><font size=3></font></p>
<h1><font size=5><span twffan="done">附录</span><span twffan="done"> </span><span twffan="done">二：例程</span></font></h1>
<p><span twffan="done"><font size=3>下面是一个关于多重继承的虚函数表访问的例程：</font></span></p>
<p><font face="Times New Roman" size=3>&nbsp;</font></p>
<p><span twffan="done">#include</span><span twffan="done"> <span twffan="done">&lt;iostream&gt;</span></span></p>
<p><span twffan="done">using</span><span twffan="done"> <span twffan="done">namespace</span> std;</span></p>
<p>&nbsp;</p>
<p><span twffan="done">class</span><span twffan="done"> Base1 {</span></p>
<p><span twffan="done">public</span><span twffan="done">:</span></p>
<p><span twffan="done"><span twffan="done">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span twffan="done">virtual</span> <span twffan="done">void</span> f() { cout &lt;&lt; <span twffan="done">"Base1::f"</span> &lt;&lt; endl; }</span></p>
<p><span twffan="done"><span twffan="done">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span twffan="done">virtual</span> <span twffan="done">void</span> g() { cout &lt;&lt; <span twffan="done">"Base1::g"</span> &lt;&lt; endl; }</span></p>
<p><span twffan="done"><span twffan="done">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span twffan="done">virtual</span> <span twffan="done">void</span> h() { cout &lt;&lt; <span twffan="done">"Base1::h"</span> &lt;&lt; endl; }</span></p>
<p>&nbsp;</p>
<p><span twffan="done">};</span></p>
<p>&nbsp;</p>
<p><span twffan="done">class</span><span twffan="done"> Base2 {</span></p>
<p><span twffan="done">public</span><span twffan="done">:</span></p>
<p><span twffan="done"><span twffan="done">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span twffan="done">virtual</span> <span twffan="done">void</span> f() { cout &lt;&lt; <span twffan="done">"Base2::f"</span> &lt;&lt; endl; }</span></p>
<p><span twffan="done"><span twffan="done">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span twffan="done">virtual</span> <span twffan="done">void</span> g() { cout &lt;&lt; <span twffan="done">"Base2::g"</span> &lt;&lt; endl; }</span></p>
<p><span twffan="done"><span twffan="done">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span twffan="done">virtual</span> <span twffan="done">void</span> h() { cout &lt;&lt; <span twffan="done">"Base2::h"</span> &lt;&lt; endl; }</span></p>
<p><span twffan="done">};</span></p>
<p>&nbsp;</p>
<p><span twffan="done">class</span><span twffan="done"> Base3 {</span></p>
<p><span twffan="done">public</span><span twffan="done">:</span></p>
<p><span twffan="done"><span twffan="done">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span twffan="done">virtual</span> <span twffan="done">void</span> f() { cout &lt;&lt; <span twffan="done">"Base3::f"</span> &lt;&lt; endl; }</span></p>
<p><span twffan="done"><span twffan="done">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span twffan="done">virtual</span> <span twffan="done">void</span> g() { cout &lt;&lt; <span twffan="done">"Base3::g"</span> &lt;&lt; endl; }</span></p>
<p><span twffan="done"><span twffan="done">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span twffan="done">virtual</span> <span twffan="done">void</span> h() { cout &lt;&lt; <span twffan="done">"Base3::h"</span> &lt;&lt; endl; }</span></p>
<p><span twffan="done">};</span></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p><span twffan="done">class</span><span twffan="done"> Derive : <span twffan="done">public</span> Base1, <span twffan="done">public</span> Base2, <span twffan="done">public</span> Base3 {</span></p>
<p><span twffan="done">public</span><span twffan="done">:</span></p>
<p><span twffan="done"><span twffan="done">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span twffan="done">virtual</span> <span twffan="done">void</span> f() { cout &lt;&lt; <span twffan="done">"Driver::f"</span> &lt;&lt; endl; }</span></p>
<p><span twffan="done"><span twffan="done">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span twffan="done">virtual</span> <span twffan="done">void</span> g1() { cout &lt;&lt; <span twffan="done">"Driver::g1"</span> &lt;&lt; endl; }</span></p>
<p><span twffan="done">};</span></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p><span twffan="done">typedef</span><span twffan="done"> <span twffan="done">void</span>(*Fun)(<span twffan="done">void</span>);</span></p>
<p>&nbsp;</p>
<p><span twffan="done">int</span><span twffan="done"> main() </span></p>
<p><span twffan="done">{</span></p>
<p><span twffan="done"><span twffan="done">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>Fun pFun = NULL;</span></p>
<p>&nbsp;</p>
<p><span twffan="done"><span twffan="done">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>Derive d;</span></p>
<p><span twffan="done"><span twffan="done">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span twffan="done">int</span>** pVtab = (<span twffan="done">int</span>**)&amp;d;</span></p>
<p>&nbsp;</p>
<p><span twffan="done"><span twffan="done">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><strong><span twffan="done">//Base1's vtable</span></strong></span></p>
<p><span twffan="done"><span twffan="done">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span twffan="done">//pFun = (Fun)*((int*)*(int*)((int*)&amp;d+0)+0);</span></span></p>
<p><span twffan="done"><span twffan="done">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>pFun = (Fun)pVtab[<span twffan="done">0</span>][<span twffan="done">0</span>];</span></p>
<p><span twffan="done"><span twffan="done">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>pFun();</span></p>
<p>&nbsp;</p>
<p><span twffan="done"><span twffan="done">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span twffan="done">//pFun = (Fun)*((int*)*(int*)((int*)&amp;d+0)+1);</span></span></p>
<p><span twffan="done"><span twffan="done">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>pFun = (Fun)pVtab[<span twffan="done">0</span>][<span twffan="done">1</span>];</span></p>
<p><span twffan="done"><span twffan="done">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>pFun();</span></p>
<p>&nbsp;</p>
<p><span twffan="done"><span twffan="done">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span twffan="done">//pFun = (Fun)*((int*)*(int*)((int*)&amp;d+0)+2);</span></span></p>
<p><span twffan="done"><span twffan="done">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>pFun = (Fun)pVtab[<span twffan="done">0</span>][<span twffan="done">2</span>];</span></p>
<p><span twffan="done"><span twffan="done">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>pFun();</span></p>
<p>&nbsp;</p>
<p><span twffan="done"><span twffan="done">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span twffan="done">//Derive's vtable</span></span></p>
<p><span twffan="done"><span twffan="done">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span twffan="done">//pFun = (Fun)*((int*)*(int*)((int*)&amp;d+0)+3);</span></span></p>
<p><span twffan="done"><span twffan="done">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>pFun = (Fun)pVtab[<span twffan="done">0</span>][<span twffan="done">3</span>];</span></p>
<p><span twffan="done"><span twffan="done">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>pFun();</span></p>
<p>&nbsp;</p>
<p><span twffan="done"><span twffan="done">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span twffan="done">//The tail of the vtable</span></span></p>
<p><span twffan="done"><span twffan="done">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>pFun = (Fun)pVtab[<span twffan="done">0</span>][<span twffan="done">4</span>];</span></p>
<p><span twffan="done"><span twffan="done">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>cout&lt;&lt;pFun&lt;&lt;endl;</span></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p><span twffan="done"><span twffan="done">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><strong><span twffan="done">//Base2's vtable</span></strong></span></p>
<p><span twffan="done"><span twffan="done">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span twffan="done">//pFun = (Fun)*((int*)*(int*)((int*)&amp;d+1)+0);</span></span></p>
<p><span twffan="done"><span twffan="done">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>pFun = (Fun)pVtab[<span twffan="done">1</span>][<span twffan="done">0</span>];</span></p>
<p><span twffan="done"><span twffan="done">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>pFun();</span></p>
<p>&nbsp;</p>
<p><span twffan="done"><span twffan="done">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span twffan="done">//pFun = (Fun)*((int*)*(int*)((int*)&amp;d+1)+1);</span></span></p>
<p><span twffan="done"><span twffan="done">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>pFun = (Fun)pVtab[<span twffan="done">1</span>][<span twffan="done">1</span>];</span></p>
<p><span twffan="done"><span twffan="done">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>pFun();</span></p>
<p>&nbsp;</p>
<p><span twffan="done"><span twffan="done">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>pFun = (Fun)pVtab[<span twffan="done">1</span>][<span twffan="done">2</span>];</span></p>
<p><span twffan="done"><span twffan="done">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>pFun(); </span></p>
<p>&nbsp;</p>
<p><span twffan="done"><span twffan="done">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span twffan="done">//The tail of the vtable</span></span></p>
<p><span twffan="done"><span twffan="done">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>pFun = (Fun)pVtab[<span twffan="done">1</span>][<span twffan="done">3</span>];</span></p>
<p><span twffan="done"><span twffan="done">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>cout&lt;&lt;pFun&lt;&lt;endl;</span></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p><span twffan="done"><span twffan="done">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><strong><span twffan="done">//Base3's vtable</span></strong></span></p>
<p><span twffan="done"><span twffan="done">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span twffan="done">//pFun = (Fun)*((int*)*(int*)((int*)&amp;d+1)+0);</span></span></p>
<p><span twffan="done"><span twffan="done">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>pFun = (Fun)pVtab[<span twffan="done">2</span>][<span twffan="done">0</span>];</span></p>
<p><span twffan="done"><span twffan="done">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>pFun();</span></p>
<p>&nbsp;</p>
<p><span twffan="done"><span twffan="done">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span twffan="done">//pFun = (Fun)*((int*)*(int*)((int*)&amp;d+1)+1);</span></span></p>
<p><span twffan="done"><span twffan="done">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>pFun = (Fun)pVtab[<span twffan="done">2</span>][<span twffan="done">1</span>];</span></p>
<p><span twffan="done"><span twffan="done">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>pFun();</span></p>
<p>&nbsp;</p>
<p><span twffan="done"><span twffan="done">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>pFun = (Fun)pVtab[<span twffan="done">2</span>][<span twffan="done">2</span>];</span></p>
<p><span twffan="done"><span twffan="done">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>pFun(); </span></p>
<p>&nbsp;</p>
<p><span twffan="done"><span twffan="done">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span twffan="done">//The tail of the vtable</span></span></p>
<p><span twffan="done"><span twffan="done">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>pFun = (Fun)pVtab[<span twffan="done">2</span>][<span twffan="done">3</span>];</span></p>
<p><span twffan="done"><span twffan="done">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>cout&lt;&lt;pFun&lt;&lt;endl;</span></p>
<p>&nbsp;</p>
<p><span twffan="done"><span twffan="done">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span twffan="done">return</span> <span twffan="done">0</span>;</span></p>
<p><span twffan="done">}</span></p>
<p>&nbsp;</p>
<p><font size=3><strong><font face="Times New Roman">(</font></strong><strong><span twffan="done">转载时请注明作者和出处。未经许可，请勿用于商业用途</span><font face="Times New Roman">)</font></strong></font></p>
<p><font face="Times New Roman" size=3>&nbsp;</font></p>
<p><font size=3><span twffan="done">更多文章请访问我的</span><font face="Times New Roman">Blog: </font></font><a href="http://blog.csdn.net/haoel"><font face="Times New Roman" color=#000080 size=3>http://blog.csdn.net/haoel</font></a><font face="Times New Roman" size=3> </font></p><img src ="http://www.cppblog.com/mzty/aggbug/42877.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mzty/" target="_blank">梦在天涯</a> 2008-02-18 13:29 <a href="http://www.cppblog.com/mzty/archive/2008/02/18/42877.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>随笔总结</title><link>http://www.cppblog.com/mzty/archive/2008/01/17/41318.html</link><dc:creator>梦在天涯</dc:creator><author>梦在天涯</author><pubDate>Thu, 17 Jan 2008 02:14:00 GMT</pubDate><guid>http://www.cppblog.com/mzty/archive/2008/01/17/41318.html</guid><wfw:comment>http://www.cppblog.com/mzty/comments/41318.html</wfw:comment><comments>http://www.cppblog.com/mzty/archive/2008/01/17/41318.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cppblog.com/mzty/comments/commentRss/41318.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mzty/services/trackbacks/41318.html</trackback:ping><description><![CDATA[<p><br>总结：<a href="http://www.cppblog.com/mzty/archive/2007/08/13/29922.html"><br><br>http://www.cppblog.com/mzty/archive/2007/08/13/29922.html</a>&nbsp; C++高级</p>
<p><a href="http://www.cppblog.com/mzty/archive/2007/03/02/19109.html">http://www.cppblog.com/mzty/archive/2007/03/02/19109.html</a>&nbsp; C++基础</p>
<p><a href="http://www.cppblog.com/mzty/archive/2007/04/16/22064.html">http://www.cppblog.com/mzty/archive/2007/04/16/22064.html</a>&nbsp; C#界面，C++核心算法</p>
<p><a href="http://www.cppblog.com/mzty/archive/2007/03/04/19163.html">http://www.cppblog.com/mzty/archive/2007/03/04/19163.html</a>&nbsp; 设计模式</p>
<p><a href="http://www.cppblog.com/mzty/archive/2007/03/29/20893.html">http://www.cppblog.com/mzty/archive/2007/03/29/20893.html</a>&nbsp; 64bit，FW3.0随笔分类 </p>
<p><a href="http://www.cppblog.com/mzty/archive/2007/03/29/20892.html">http://www.cppblog.com/mzty/archive/2007/03/29/20892.html</a>&nbsp; windows脚本技术</p>
<p><a href="http://www.cppblog.com/mzty/archive/2007/03/04/19167.html">http://www.cppblog.com/mzty/archive/2007/03/04/19167.html</a>&nbsp; C#基础</p><img src ="http://www.cppblog.com/mzty/aggbug/41318.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mzty/" target="_blank">梦在天涯</a> 2008-01-17 10:14 <a href="http://www.cppblog.com/mzty/archive/2008/01/17/41318.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C#的Form通过CLI调用C++的DLL</title><link>http://www.cppblog.com/mzty/archive/2007/12/25/39610.html</link><dc:creator>梦在天涯</dc:creator><author>梦在天涯</author><pubDate>Tue, 25 Dec 2007 11:14:00 GMT</pubDate><guid>http://www.cppblog.com/mzty/archive/2007/12/25/39610.html</guid><wfw:comment>http://www.cppblog.com/mzty/comments/39610.html</wfw:comment><comments>http://www.cppblog.com/mzty/archive/2007/12/25/39610.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/mzty/comments/commentRss/39610.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mzty/services/trackbacks/39610.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 一 方法&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;C#的project调用C++的DLL，一般也有3中方法：&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1）最简单的方法，通过PInvoke，但是只能调用全局function，不能调用Class。&nbsp;&nbsp;&...&nbsp;&nbsp;<a href='http://www.cppblog.com/mzty/archive/2007/12/25/39610.html'>阅读全文</a><img src ="http://www.cppblog.com/mzty/aggbug/39610.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mzty/" target="_blank">梦在天涯</a> 2007-12-25 19:14 <a href="http://www.cppblog.com/mzty/archive/2007/12/25/39610.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>NativeC++通过CLI调用C#的Form</title><link>http://www.cppblog.com/mzty/archive/2007/12/25/39555.html</link><dc:creator>梦在天涯</dc:creator><author>梦在天涯</author><pubDate>Tue, 25 Dec 2007 02:51:00 GMT</pubDate><guid>http://www.cppblog.com/mzty/archive/2007/12/25/39555.html</guid><wfw:comment>http://www.cppblog.com/mzty/comments/39555.html</wfw:comment><comments>http://www.cppblog.com/mzty/archive/2007/12/25/39555.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/mzty/comments/commentRss/39555.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mzty/services/trackbacks/39555.html</trackback:ping><description><![CDATA[<br>一 调用方法<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Native C++的project调用C#的DLL，一般有3中方法：<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1）通过COM封装<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2）通过CLI/C++的Wrapper<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;3)&nbsp; 在VS中可以直接修改NativeC++的project或是部分文件为使用CLR来调用C#的DLL<br><br>二 实例<br>1）C#的一个MyForm类，有public函数ShowMyForm（）<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">using</span><span style="COLOR: #000000">&nbsp;System;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">using</span><span style="COLOR: #000000">&nbsp;System.Collections.Generic;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">using</span><span style="COLOR: #000000">&nbsp;System.Text;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">using</span><span style="COLOR: #000000">&nbsp;System.Windows.Forms;<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><span style="COLOR: #0000ff">namespace</span><span style="COLOR: #000000">&nbsp;CsharpDLL<br><img id=Codehighlighter1_116_1454_Open_Image onclick="this.style.display='none'; Codehighlighter1_116_1454_Open_Text.style.display='none'; Codehighlighter1_116_1454_Closed_Image.style.display='inline'; Codehighlighter1_116_1454_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_116_1454_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_116_1454_Closed_Text.style.display='none'; Codehighlighter1_116_1454_Open_Image.style.display='inline'; Codehighlighter1_116_1454_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top></span><span id=Codehighlighter1_116_1454_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_116_1454_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">&nbsp;MyForm&nbsp;:&nbsp;Form<br><img id=Codehighlighter1_153_1452_Open_Image onclick="this.style.display='none'; Codehighlighter1_153_1452_Open_Text.style.display='none'; Codehighlighter1_153_1452_Closed_Image.style.display='inline'; Codehighlighter1_153_1452_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_153_1452_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_153_1452_Closed_Text.style.display='none'; Codehighlighter1_153_1452_Open_Image.style.display='inline'; Codehighlighter1_153_1452_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span id=Codehighlighter1_153_1452_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_153_1452_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">private</span><span style="COLOR: #000000">&nbsp;Button&nbsp;button1;<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>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;ShowMyForm()<br><img id=Codehighlighter1_229_270_Open_Image onclick="this.style.display='none'; Codehighlighter1_229_270_Open_Text.style.display='none'; Codehighlighter1_229_270_Closed_Image.style.display='inline'; Codehighlighter1_229_270_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_229_270_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_229_270_Closed_Text.style.display='none'; Codehighlighter1_229_270_Open_Image.style.display='inline'; Codehighlighter1_229_270_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span id=Codehighlighter1_229_270_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_229_270_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">.ShowDialog();<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">&nbsp;MyForm()<br><img id=Codehighlighter1_304_448_Open_Image onclick="this.style.display='none'; Codehighlighter1_304_448_Open_Text.style.display='none'; Codehighlighter1_304_448_Closed_Image.style.display='inline'; Codehighlighter1_304_448_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_304_448_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_304_448_Closed_Text.style.display='none'; Codehighlighter1_304_448_Open_Image.style.display='inline'; Codehighlighter1_304_448_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span id=Codehighlighter1_304_448_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_304_448_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;InitializeComponent();<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">.Text&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">MyForm</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">.StartPosition&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;FormStartPosition.CenterScreen;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">private</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;InitializeComponent()<br><img id=Codehighlighter1_501_1303_Open_Image onclick="this.style.display='none'; Codehighlighter1_501_1303_Open_Text.style.display='none'; Codehighlighter1_501_1303_Closed_Image.style.display='inline'; Codehighlighter1_501_1303_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_501_1303_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_501_1303_Closed_Text.style.display='none'; Codehighlighter1_501_1303_Open_Image.style.display='inline'; Codehighlighter1_501_1303_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span id=Codehighlighter1_501_1303_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_501_1303_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">.button1&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000">&nbsp;System.Windows.Forms.Button();<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">.SuspendLayout();<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;button1<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;</span><span style="COLOR: #008000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">.button1.Location&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000">&nbsp;System.Drawing.Point(</span><span style="COLOR: #000000">110</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">74</span><span style="COLOR: #000000">);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">.button1.Name&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">button1</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">.button1.Size&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000">&nbsp;System.Drawing.Size(</span><span style="COLOR: #000000">75</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">23</span><span style="COLOR: #000000">);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">.button1.TabIndex&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">.button1.Text&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">TestMessageBox</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">.button1.UseVisualStyleBackColor&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">true</span><span style="COLOR: #000000">;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">.button1.Click&nbsp;</span><span style="COLOR: #000000">+=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000">&nbsp;System.EventHandler(</span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">.button1_Click);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;MyForm<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;</span><span style="COLOR: #008000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">.ClientSize&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000">&nbsp;System.Drawing.Size(</span><span style="COLOR: #000000">292</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">266</span><span style="COLOR: #000000">);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">.Controls.Add(</span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">.button1);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">.Name&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">MyForm</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">.ResumeLayout(</span><span style="COLOR: #0000ff">false</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/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</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>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">private</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;button1_Click(</span><span style="COLOR: #0000ff">object</span><span style="COLOR: #000000">&nbsp;sender,&nbsp;EventArgs&nbsp;e)<br><img id=Codehighlighter1_1377_1446_Open_Image onclick="this.style.display='none'; Codehighlighter1_1377_1446_Open_Text.style.display='none'; Codehighlighter1_1377_1446_Closed_Image.style.display='inline'; Codehighlighter1_1377_1446_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_1377_1446_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_1377_1446_Closed_Text.style.display='none'; Codehighlighter1_1377_1446_Open_Image.style.display='inline'; Codehighlighter1_1377_1446_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span id=Codehighlighter1_1377_1446_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_1377_1446_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MessageBox.Show(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">Hello,&nbsp;i&nbsp;am&nbsp;a&nbsp;Csharp&nbsp;Form!</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;}</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></span></div>
<br>2）C#的exe调用<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">using</span><span style="COLOR: #000000">&nbsp;System;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">using</span><span style="COLOR: #000000">&nbsp;System.Collections.Generic;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">using</span><span style="COLOR: #000000">&nbsp;System.Text;<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><span style="COLOR: #0000ff">namespace</span><span style="COLOR: #000000">&nbsp;CsharpTest<br><img id=Codehighlighter1_89_411_Open_Image onclick="this.style.display='none'; Codehighlighter1_89_411_Open_Text.style.display='none'; Codehighlighter1_89_411_Closed_Image.style.display='inline'; Codehighlighter1_89_411_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_89_411_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_89_411_Closed_Text.style.display='none'; Codehighlighter1_89_411_Open_Image.style.display='inline'; Codehighlighter1_89_411_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top></span><span id=Codehighlighter1_89_411_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_89_411_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">&nbsp;Program<br><img id=Codehighlighter1_113_409_Open_Image onclick="this.style.display='none'; Codehighlighter1_113_409_Open_Text.style.display='none'; Codehighlighter1_113_409_Closed_Image.style.display='inline'; Codehighlighter1_113_409_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_113_409_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_113_409_Closed_Text.style.display='none'; Codehighlighter1_113_409_Open_Image.style.display='inline'; Codehighlighter1_113_409_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span id=Codehighlighter1_113_409_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_113_409_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">static</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;Main(</span><span style="COLOR: #0000ff">string</span><span style="COLOR: #000000">[]&nbsp;args)<br><img id=Codehighlighter1_163_403_Open_Image onclick="this.style.display='none'; Codehighlighter1_163_403_Open_Text.style.display='none'; Codehighlighter1_163_403_Closed_Image.style.display='inline'; Codehighlighter1_163_403_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_163_403_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_163_403_Closed_Text.style.display='none'; Codehighlighter1_163_403_Open_Image.style.display='inline'; Codehighlighter1_163_403_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span id=Codehighlighter1_163_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><span id=Codehighlighter1_163_403_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&n