﻿<?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++博客-woaidongmao-随笔分类-C++存档</title><link>http://www.cppblog.com/woaidongmao/category/6005.html</link><description>文章均收录自他人博客，但不喜标题前加-[转贴]，因其丑陋，见谅！~</description><language>zh-cn</language><lastBuildDate>Fri, 26 Dec 2008 16:08:37 GMT</lastBuildDate><pubDate>Fri, 26 Dec 2008 16:08:37 GMT</pubDate><ttl>60</ttl><item><title>如何编写异常安全的C++代码</title><link>http://www.cppblog.com/woaidongmao/archive/2008/12/26/70475.html</link><dc:creator>肥仔</dc:creator><author>肥仔</author><pubDate>Fri, 26 Dec 2008 15:06:00 GMT</pubDate><guid>http://www.cppblog.com/woaidongmao/archive/2008/12/26/70475.html</guid><wfw:comment>http://www.cppblog.com/woaidongmao/comments/70475.html</wfw:comment><comments>http://www.cppblog.com/woaidongmao/archive/2008/12/26/70475.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/woaidongmao/comments/commentRss/70475.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/woaidongmao/services/trackbacks/70475.html</trackback:ping><description><![CDATA[<p></p> <p style="text-justify: inter-ideograph; line-height: 150%; text-align: justify">　关于<span lang="EN-US">C++</span>中异常的争论何其多也，但往往是一些不合事实的误解。异常曾经是一个难以用好的语言特性，幸运的是，随着<span lang="EN-US">C++</span>社区经验的积累，今天我们已经有足够的知识轻松编写异常安全的代码了，而且编写异常安全的代码一般也不会对性能造成影响。<span lang="EN-US"><?xml:namespace prefix = o /><o:p></o:p></span></p> <p style="text-justify: inter-ideograph; line-height: 150%; text-align: justify">　　使用异常还是返回错误码？这是个争论不休的话题。大家一定听说过这样的说法：只有在真正异常的时候，才使用异常。那什么是<span lang="EN-US">“</span>真正异常的时候<span lang="EN-US">”</span>？在回答这个问题以前，让我们先看一看程序设计中的不变式原理。<span lang="EN-US"><o:p></o:p></span></p> <p style="text-justify: inter-ideograph; line-height: 150%; text-align: justify">　　对象就是属性聚合加方法，如何判定一个对象的属性聚合是不是处于逻辑上正确的状态呢？这可以通过一系列的断言，最后下一个结论说：这个对象的属性聚合逻辑上是正确的或者是有问题的。这些断言就是衡量对象属性聚合对错的不变式。<span lang="EN-US"><o:p></o:p></span></p> <p style="text-justify: inter-ideograph; line-height: 150%; text-align: justify">　　我们通常在函数调用中，实施不变式的检查。不变式分为三类：前条件，后条件和不变式。前条件是指在函数调用之前，必须满足的逻辑条件，后条件是函数调用后必须满足的逻辑条件，不变式则是整个函数执行中都必须满足的条件。在我们的讨论中，不变式既是前条件又是后条件。前条件是必须满足的，如果不满足，那就是程序逻辑错误，后条件则不一定。现在，我们可以用不变式来严格定义异常状况了：满足前条件，但是无法满足后条件，即为异常状况。当且仅当发生异常状况时，才抛出异常。<span lang="EN-US"><o:p></o:p></span></p> <p style="text-justify: inter-ideograph; line-height: 150%; text-align: justify">　　关于何时抛出异常的回答中，并不排斥返回值报告错误，而且这两者是正交的。然而，从我们经验上来说，完全可以在这两者中加以选择，这又是为什么呢？事实上，当我们做出这种选择时，必然意味着接口语意的改变，在不改变接口的情况下，其实是无法选择的<span lang="EN-US">(</span>试试看，用返回值处理构造函数中的错误<span lang="EN-US">)</span>。通过不变式区别出正常和异常状况，还可以更好地提炼接口。<span lang="EN-US"><o:p></o:p></span></p> <p style="text-justify: inter-ideograph; line-height: 150%; text-align: justify">　　对于异常安全的评定，可分为三个级别：基本保证、强保证和不会失败。<span lang="EN-US"><o:p></o:p></span></p> <p style="text-justify: inter-ideograph; line-height: 150%; text-align: justify">　　基本保证：确保出现异常时程序（对象）处于未知但有效的状态。所谓有效，即对象的不变式检查全部通过。<span lang="EN-US"><br></span>　　强保证：确保操作的事务性，要么成功，程序处于目标状态，要么不发生改变。<span lang="EN-US"><br></span>　　不会失败：对于大多数函数来说，这是很难保证的。对于<span lang="EN-US">C++</span>程序，至少析构函数、释放函数和<span lang="EN-US">swap</span>函数要确保不会失败，这是编写异常安全代码的基础。<span lang="EN-US"><o:p></o:p></span></p> <p style="text-justify: inter-ideograph; line-height: 150%; text-align: justify">　　首先从异常情况下资源管理的问题开始<span lang="EN-US">.</span>很多人可能都这么干过<span lang="EN-US">:<o:p></o:p></span></p> <div style="border-right: #0099cc 1pt solid; padding-right: 4pt; border-top: #0099cc 1pt solid; padding-left: 4pt; background: #ddedfb; padding-bottom: 4pt; margin-left: 3.75pt; border-left: #0099cc 1pt solid; margin-right: 3.75pt; padding-top: 4pt; border-bottom: #0099cc 1pt solid; mso-element: para-border-div; mso-border-alt: solid #0099cc .75pt"> <p class="code" style="text-justify: inter-ideograph; background: #ddedfb; margin: 3.75pt 0cm; text-align: justify"><span lang="EN-US" style="font-size: 12pt; color: windowtext; font-family: 宋体">Type* obj = new Type;<br>try{&nbsp; do_something...}<br>catch(...){ delete obj; throw;}<o:p></o:p></span></p></div> <p style="text-justify: inter-ideograph; line-height: 150%; text-align: justify">　　不要这么做<span lang="EN-US">!</span>这么做只会使你的代码看上去混乱<span lang="EN-US">,</span>而且会降低效率<span lang="EN-US">,</span>这也是一直以来异常名声不大好的原因之一<span lang="EN-US">. </span>请借助于<span lang="EN-US">RAII</span>技术来完成这样的工作<span lang="EN-US">:<o:p></o:p></span></p> <div style="border-right: #0099cc 1pt solid; padding-right: 4pt; border-top: #0099cc 1pt solid; padding-left: 4pt; background: #ddedfb; padding-bottom: 4pt; margin-left: 3.75pt; border-left: #0099cc 1pt solid; margin-right: 3.75pt; padding-top: 4pt; border-bottom: #0099cc 1pt solid; mso-element: para-border-div; mso-border-alt: solid #0099cc .75pt"> <p class="code" style="text-justify: inter-ideograph; background: #ddedfb; margin: 3.75pt 0cm; text-align: justify"><span lang="EN-US" style="font-size: 12pt; color: windowtext; font-family: 宋体">auto_ptr&lt;Type&gt; obj_ptr(new Type);<br>do_something...<o:p></o:p></span></p></div> <p style="text-justify: inter-ideograph; line-height: 150%; text-align: justify">　　这样的代码简洁、安全而且无损于效率。当你不关心或是无法处理异常时<span lang="EN-US">,</span>请不要试图捕获它。并非使用<span lang="EN-US">try...catch</span>才能编写异常安全的代码<span lang="EN-US">,</span>大部分异常安全的代码都不需要<span lang="EN-US">try...catch</span>。我承认，现实世界并非总是如上述的例子那样简单，但是这个例子确实可以代表很多异常安全代码的做法。在这个例子中，<span lang="EN-US">boost::scoped_ptr</span>是<span lang="EN-US">auto_ptr</span>一个更适合的替代品。<span lang="EN-US"><o:p></o:p></span></p> <p style="text-justify: inter-ideograph; line-height: 150%; text-align: justify">　　现在来考虑这样一个构造函数：<span lang="EN-US"><o:p></o:p></span></p> <div style="border-right: #0099cc 1pt solid; padding-right: 4pt; border-top: #0099cc 1pt solid; padding-left: 4pt; background: #ddedfb; padding-bottom: 4pt; margin-left: 3.75pt; border-left: #0099cc 1pt solid; margin-right: 3.75pt; padding-top: 4pt; border-bottom: #0099cc 1pt solid; mso-element: para-border-div; mso-border-alt: solid #0099cc .75pt"> <p class="code" style="text-justify: inter-ideograph; background: #ddedfb; margin: 3.75pt 0cm; text-align: justify"><span lang="EN-US" style="font-size: 12pt; color: windowtext; font-family: 宋体">Type() : m_a(new TypeA), m_b(new TypeB){}<o:p></o:p></span></p></div> <p style="text-justify: inter-ideograph; line-height: 150%; text-align: justify">　　假设成员变量<span lang="EN-US">m_a</span>和<span lang="EN-US">m_b</span>是原始的指针类型，并且和<span lang="EN-US">Type</span>内的申明顺序一致。这样的代码是不安全的，它存在资源泄漏问题，构造函数的失败回滚机制无法应对这样的问题。如果<span lang="EN-US">new TypeB</span>抛出异常<span lang="EN-US">,new TypeA</span>返回的资源是得不到释放机会的<span lang="EN-US">.</span>曾经<span lang="EN-US">,</span>很多人用这样的方法避免异常<span lang="EN-US">:<o:p></o:p></span></p> <div style="border-right: #0099cc 1pt solid; padding-right: 4pt; border-top: #0099cc 1pt solid; padding-left: 4pt; background: #ddedfb; padding-bottom: 4pt; margin-left: 3.75pt; border-left: #0099cc 1pt solid; margin-right: 3.75pt; padding-top: 4pt; border-bottom: #0099cc 1pt solid; mso-element: para-border-div; mso-border-alt: solid #0099cc .75pt"> <p class="code" style="text-justify: inter-ideograph; background: #ddedfb; margin: 3.75pt 0cm; text-align: justify"><span lang="EN-US" style="font-size: 12pt; color: windowtext; font-family: 宋体">Type() : m_a(NULL), m_b(NULL){<br>&nbsp;&nbsp;&nbsp;&nbsp; auto_ptr&lt;TypeA&gt; tmp_a(new TypeA);<br>&nbsp;&nbsp;&nbsp;&nbsp; auto_ptr&lt;TypeB&gt; tmp_b(new TypeB);<br>&nbsp;&nbsp;&nbsp;&nbsp; m_a = tmp_a.release();<br>&nbsp;&nbsp;&nbsp;&nbsp; m_b = tmp_b.release();<br>}<o:p></o:p></span></p></div> <p style="text-justify: inter-ideograph; line-height: 150%; text-align: justify">　　当然<span lang="EN-US">,</span>这样的方法确实是能够实现异常安全的代码的<span lang="EN-US">,</span>而且其中实现思想将是非常重要的<span lang="EN-US">,</span>在如何实现强保证的异常安全代码中会采用这种思想<span lang="EN-US">.</span>然而这种做法不够彻底，至少析构函数还是要手动完成的。我们仍然可以借助<span lang="EN-US">RAII</span>技术，把这件事做得更为彻底：<span lang="EN-US">shared_ptr&lt;TypeA&gt; m_a; shared_ptr&lt;TypeB&gt; m_b;</span>这样<span lang="EN-US">,</span>我们就可以轻而易举地写出异常安全的代码<span lang="EN-US">:<o:p></o:p></span></p> <div style="border-right: #0099cc 1pt solid; padding-right: 4pt; border-top: #0099cc 1pt solid; padding-left: 4pt; background: #ddedfb; padding-bottom: 4pt; margin-left: 3.75pt; border-left: #0099cc 1pt solid; margin-right: 3.75pt; padding-top: 4pt; border-bottom: #0099cc 1pt solid; mso-element: para-border-div; mso-border-alt: solid #0099cc .75pt"> <p class="code" style="text-justify: inter-ideograph; background: #ddedfb; margin: 3.75pt 0cm; text-align: justify"><span lang="EN-US" style="font-size: 12pt; color: windowtext; font-family: 宋体">Type() : m_a(new TypeA), m_b(new TypeB){}<o:p></o:p></span></p></div> <p style="text-justify: inter-ideograph; line-height: 150%; text-align: justify">　　如果你觉得<span lang="EN-US">shared_ptr</span>的性能不能满足要求，可以编写一个接口类似<span lang="EN-US">scoped_ptr</span>的智能指针类<span lang="EN-US">,</span>在析构函数中释放资源即可。如果类设计成不可复制的，也可以直接用<span lang="EN-US">scoped_ptr</span>。强烈建议不要把<span lang="EN-US">auto_ptr</span>作为数据成员使用<span lang="EN-US">,scoped_ptr</span>虽然名字不大好，但是至少很安全而且不会导致混乱。<span lang="EN-US"><o:p></o:p></span></p> <p style="text-justify: inter-ideograph; line-height: 150%; text-align: justify">　　<span lang="EN-US">RAII</span>技术并不仅仅用于上述例子中，所有必须成对出现的操作都可以通过这一技术完成而不必<span lang="EN-US">try...catch.</span>下面的代码也是常见的：<span lang="EN-US"><o:p></o:p></span></p> <div style="border-right: #0099cc 1pt solid; padding-right: 4pt; border-top: #0099cc 1pt solid; padding-left: 4pt; background: #ddedfb; padding-bottom: 4pt; margin-left: 3.75pt; border-left: #0099cc 1pt solid; margin-right: 3.75pt; padding-top: 4pt; border-bottom: #0099cc 1pt solid; mso-element: para-border-div; mso-border-alt: solid #0099cc .75pt"> <p class="code" style="text-justify: inter-ideograph; background: #ddedfb; margin: 3.75pt 0cm; text-align: justify"><span lang="EN-US" style="font-size: 12pt; color: windowtext; font-family: 宋体">a_lock.lock(); <br>try{ ...} catch(...) {a_lock.unlock();throw;}<br>a_lock.unlock(); <o:p></o:p></span></p></div> <p style="text-justify: inter-ideograph; line-height: 150%; text-align: justify">　　可以这样解决，先提供一个成对操作的辅助类：<span lang="EN-US"><o:p></o:p></span></p> <div style="border-right: #0099cc 1pt solid; padding-right: 4pt; border-top: #0099cc 1pt solid; padding-left: 4pt; background: #ddedfb; padding-bottom: 4pt; margin-left: 3.75pt; border-left: #0099cc 1pt solid; margin-right: 3.75pt; padding-top: 4pt; border-bottom: #0099cc 1pt solid; mso-element: para-border-div; mso-border-alt: solid #0099cc .75pt"> <p class="code" style="text-justify: inter-ideograph; background: #ddedfb; margin: 3.75pt 0cm; text-align: justify"><span lang="EN-US" style="font-size: 12pt; color: windowtext; font-family: 宋体">struct scoped_lock{<br>&nbsp;&nbsp;&nbsp; explicit scoped_lock(Lock&amp; lock) : m_l(lock){m_l.lock();}<br>&nbsp;&nbsp;&nbsp; ~scoped_lock(){m_l.unlock();}<br>private:&nbsp; <br>&nbsp;&nbsp;&nbsp; Lock&amp; m_l;<br>};<o:p></o:p></span></p></div> <p style="text-justify: inter-ideograph; line-height: 150%; text-align: justify">　　然后，代码只需这样写：<span lang="EN-US"><o:p></o:p></span></p> <div style="border-right: #0099cc 1pt solid; padding-right: 4pt; border-top: #0099cc 1pt solid; padding-left: 4pt; background: #ddedfb; padding-bottom: 4pt; margin-left: 3.75pt; border-left: #0099cc 1pt solid; margin-right: 3.75pt; padding-top: 4pt; border-bottom: #0099cc 1pt solid; mso-element: para-border-div; mso-border-alt: solid #0099cc .75pt"> <p class="code" style="text-justify: inter-ideograph; background: #ddedfb; margin: 3.75pt 0cm; text-align: justify"><span lang="EN-US" style="font-size: 12pt; color: windowtext; font-family: 宋体">scoped_lock guard(a_lock);<br>do_something...<o:p></o:p></span></p></div> <p style="text-justify: inter-ideograph; line-height: 150%; text-align: justify">　　清晰而优雅！继续考察这个例子<span lang="EN-US">,</span>假设我们并不需要成对操作<span lang="EN-US">, </span>显然，修改<span lang="EN-US">scoped_lock</span>构造函数即可解决问题。然而，往往方法名称和参数也不是那么固定的，怎么办？可以借助这样一个辅助类：<span lang="EN-US"><o:p></o:p></span></p> <div style="border-right: #0099cc 1pt solid; padding-right: 4pt; border-top: #0099cc 1pt solid; padding-left: 4pt; background: #ddedfb; padding-bottom: 4pt; margin-left: 3.75pt; border-left: #0099cc 1pt solid; margin-right: 3.75pt; padding-top: 4pt; border-bottom: #0099cc 1pt solid; mso-element: para-border-div; mso-border-alt: solid #0099cc .75pt"> <p class="code" style="text-justify: inter-ideograph; background: #ddedfb; margin: 3.75pt 0cm; text-align: justify"><span lang="EN-US" style="font-size: 12pt; color: windowtext; font-family: 宋体">template&lt;typename FEnd, typename FBegin&gt;<br>struct pair_guard{<br>&nbsp;&nbsp;&nbsp; pair_guard(FEnd fe, FBegin fb) : m_fe(fe) {if (fb) fb();}<br>&nbsp;&nbsp;&nbsp;&nbsp; ~pair_guard(){m_fe();}<br>private:<br>&nbsp;&nbsp;&nbsp;&nbsp; FEnd m_fe;<br>&nbsp;&nbsp;&nbsp;&nbsp; ...//</span><span style="font-size: 12pt; color: windowtext; font-family: 宋体">禁止复制<span lang="EN-US"><br>};<br>typedef pair_guard&lt;function&lt;void () &gt; , function&lt;void()&gt; &gt; simple_pair_guard;<o:p></o:p></span></span></p></div> <p style="text-justify: inter-ideograph; line-height: 150%; text-align: justify">　　好了，借助<span lang="EN-US">boost</span>库<span lang="EN-US">,</span>我们可以这样来编写代码了：<span lang="EN-US"><o:p></o:p></span></p> <div style="border-right: #0099cc 1pt solid; padding-right: 4pt; border-top: #0099cc 1pt solid; padding-left: 4pt; background: #ddedfb; padding-bottom: 4pt; margin-left: 3.75pt; border-left: #0099cc 1pt solid; margin-right: 3.75pt; padding-top: 4pt; border-bottom: #0099cc 1pt solid; mso-element: para-border-div; mso-border-alt: solid #0099cc .75pt"> <p class="code" style="text-justify: inter-ideograph; background: #ddedfb; margin: 3.75pt 0cm; text-align: justify"><span lang="EN-US" style="font-size: 12pt; color: windowtext; font-family: 宋体">simple_pair_guard guard(bind(&amp;Lock::unlock, a_lock), bind(&amp;Lock::lock, a_lock) );<br>do_something...<o:p></o:p></span></p></div> <p style="text-justify: inter-ideograph; line-height: 150%; text-align: justify">　　我承认，这样的代码不如前面的简洁和容易理解，但是它更灵活<span lang="EN-US">,</span>无论函数名称是什么，都可以拿来结对。我们可以加强对<span lang="EN-US">bind</span>的运用，结合占位符和<span lang="EN-US">reference_wrapper,</span>就可以处理函数参数、动态绑定变量。所有我们在<span lang="EN-US">catch</span>内外的相同工作，交给<span lang="EN-US">pair_guard</span>去完成即可。<span lang="EN-US"><o:p></o:p></span></p> <p style="text-justify: inter-ideograph; line-height: 150%; text-align: justify">　　考察前面的几个例子，也许你已经发现了，所谓异常安全的代码，竟然就是如何避免<span lang="EN-US">try...catch</span>的代码，这和直觉似乎是违背的。有些时候，事情就是如此违背直觉。异常是无处不在的，当你不需要关心异常或者无法处理异常的时候，就应该避免捕获异常。除非你打算捕获所有异常，否则，请务必把未处理的异常再次抛出。<span lang="EN-US">try...catch</span>的方式固然能够写出异常安全的代码，但是那样的代码无论是清晰性和效率都是难以忍受的，而这正是很多人抨击<span lang="EN-US">C++</span>异常的理由。在<span lang="EN-US">C++</span>的世界，就应该按照<span lang="EN-US">C++</span>的法则来行事。<span lang="EN-US"><o:p></o:p></span></p> <p style="text-justify: inter-ideograph; line-height: 150%; text-align: justify">　　如果按照上述的原则行事，能够实现基本保证了吗？诚恳地说，基础设施有了，但技巧上还不够，让我们继续分析不够的部分。<span lang="EN-US"><o:p></o:p></span></p> <p style="text-justify: inter-ideograph; line-height: 150%; text-align: justify">　　对于一个方法常规的执行过程，我们在方法内部可能需要多次修改对象状态，在方法执行的中途，对象是可能处于非法状态的（非法状态<span lang="EN-US"> != </span>未知状态），如果此时发生异常，对象将变得无效。利用前述的手段，在<span lang="EN-US">pair_guard</span>的析构中修复对象是可行的，但缺乏效率，代码将变得复杂。最好的办法是<span lang="EN-US">......</span>是避免这么作，这么说有点不厚道，但并非毫无道理。当对象处于非法状态时，意味着此时此刻对象不能安全重入、不能共享。现实一点的做法是：<span lang="EN-US"><o:p></o:p></span></p> <p style="text-justify: inter-ideograph; line-height: 150%; text-align: justify">　　<span lang="EN-US">a.</span>每一次修改对象，都确保对象处于合法状态<span lang="EN-US"><br></span>　　<span lang="EN-US">b.</span>或者当对象处于非法状态时，所有操作决不会失败。<span lang="EN-US"><o:p></o:p></span></p> <p style="text-justify: inter-ideograph; line-height: 150%; text-align: justify">　　在接下来的强保证的讨论中细述如何做到这两点。<span lang="EN-US"><o:p></o:p></span></p> <p style="text-justify: inter-ideograph; line-height: 150%; text-align: justify">　　强保证是事务性的，这个事务性和数据库的事务性有区别，也有共通性。实现强保证的原则做法是：在可能失败的过程中计算出对象的目标状态，但是不修改对象，在决不失败的过程中，把对象替换到目标状态。考察一个不安全的字符串赋值方法：<span lang="EN-US"><o:p></o:p></span></p> <div style="border-right: #0099cc 1pt solid; padding-right: 4pt; border-top: #0099cc 1pt solid; padding-left: 4pt; background: #ddedfb; padding-bottom: 4pt; margin-left: 3.75pt; border-left: #0099cc 1pt solid; margin-right: 3.75pt; padding-top: 4pt; border-bottom: #0099cc 1pt solid; mso-element: para-border-div; mso-border-alt: solid #0099cc .75pt"> <p class="code" style="text-justify: inter-ideograph; background: #ddedfb; margin: 3.75pt 0cm; text-align: justify"><span lang="EN-US" style="font-size: 12pt; color: windowtext; font-family: 宋体">string&amp; operator=(const string&amp; rsh){<br>&nbsp;&nbsp;&nbsp; if (this != &amp;rsh){<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; myalloc locked_pool(m_data);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; locked_pool.deallocate(m_data);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (rsh.empty())<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; m_data = NULL;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; m_data = locked_pool.allocate(rsh.size() + 1);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; never_failed_copy(m_data, rsh.m_data, rsh.size() + 1);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; return *this;<br>}<o:p></o:p></span></p></div> <p style="text-justify: inter-ideograph; line-height: 150%; text-align: justify">　　<span lang="EN-US">locked_pool</span>是为了锁定内存页。为了讨论的简单起见，我们假设只有<span lang="EN-US">locked_pool</span>构造函数和<span lang="EN-US">allocate</span>是可能抛出异常的，那么这段代码连基本保证也没有做到。若<span lang="EN-US">allocate</span>失败，则<span lang="EN-US">m_data</span>取值将是非法的。参考上面的<span lang="EN-US">b</span>条目，我们可以这样修改代码：<span lang="EN-US"><o:p></o:p></span></p> <div style="border-right: #0099cc 1pt solid; padding-right: 4pt; border-top: #0099cc 1pt solid; padding-left: 4pt; background: #ddedfb; padding-bottom: 4pt; margin-left: 3.75pt; border-left: #0099cc 1pt solid; margin-right: 3.75pt; padding-top: 4pt; border-bottom: #0099cc 1pt solid; mso-element: para-border-div; mso-border-alt: solid #0099cc .75pt"> <p class="code" style="text-justify: inter-ideograph; background: #ddedfb; margin: 3.75pt 0cm; text-align: justify"><span lang="EN-US" style="font-size: 12pt; color: windowtext; font-family: 宋体">myalloc locked_pool(m_data);<br>&nbsp;&nbsp;&nbsp; locked_pool.deallocate(m_data);&nbsp;&nbsp; //</span><span style="font-size: 12pt; color: windowtext; font-family: 宋体">进入非法状态<span lang="EN-US"><br>&nbsp;&nbsp;&nbsp; m_data = NULL;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //</span>立刻再次回到合法状态<span lang="EN-US">,</span>且不会失败<span lang="EN-US"><br>&nbsp;&nbsp;&nbsp; if(!rsh.empty()){<br>&nbsp;&nbsp;&nbsp; m_data = locked_pool.allocate(rsh.size() + 1);<br>&nbsp;&nbsp;&nbsp; never_failed_memcopy(m_data, rsh.m_data, rsh.size() + 1);<br>}<o:p></o:p></span></span></p></div> <p style="text-justify: inter-ideograph; line-height: 150%; text-align: justify">　　现在，如果<span lang="EN-US">locked_pool</span>失败，对象不发生改变。如果<span lang="EN-US">allocate</span>失败，对象是一个空字符串，这既不是初始状态，也不是我们预期的目标状态，但它是一个合法状态。我们阐明了实现基本保证所需要的技巧部分，结合前述的基础设施（<span lang="EN-US">RAII</span>的运用），完全可以实现基本保证了<span lang="EN-US">...</span>哦<span lang="EN-US">,</span>其实还是有一点疏漏，不过，那就留到最后吧。<span lang="EN-US"><o:p></o:p></span></p> <p style="text-justify: inter-ideograph; line-height: 150%; text-align: justify">　　继续，让上面的代码实现强保证：<span lang="EN-US"><o:p></o:p></span></p> <div style="border-right: #0099cc 1pt solid; padding-right: 4pt; border-top: #0099cc 1pt solid; padding-left: 4pt; background: #ddedfb; padding-bottom: 4pt; margin-left: 3.75pt; border-left: #0099cc 1pt solid; margin-right: 3.75pt; padding-top: 4pt; border-bottom: #0099cc 1pt solid; mso-element: para-border-div; mso-border-alt: solid #0099cc .75pt"> <p class="code" style="text-justify: inter-ideograph; background: #ddedfb; margin: 3.75pt 0cm; text-align: justify"><span lang="EN-US" style="font-size: 12pt; color: windowtext; font-family: 宋体">myalloc locked_pool(m_data);<br>&nbsp;&nbsp;&nbsp; char* tmp </span><span style="font-size: 12pt; color: windowtext; font-family: 宋体">＝<span lang="EN-US"> NULL;<br>&nbsp;&nbsp;&nbsp; if(!rsh.empty()){<br>&nbsp;&nbsp;&nbsp; tmp = locked_pool.allocate(rsh.size() + 1); <br>&nbsp;&nbsp;&nbsp; never_failed_memcopy(tmp, rsh.m_data, rsh.size() + 1); //</span>先生成目标状态<span lang="EN-US"><br>&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; swap(tmp, m_data);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //</span>对象安全进入目标状态<span lang="EN-US"><br>&nbsp;&nbsp;&nbsp; m_alloc.deallocate(tmp);&nbsp;&nbsp;&nbsp; //</span>释放原有资源<span lang="EN-US"><o:p></o:p></span></span></p></div> <p style="text-justify: inter-ideograph; line-height: 150%; text-align: justify">　　强保证的代码多使用了一个局部变量<span lang="EN-US">tmp</span>，先计算出目标状态放在<span lang="EN-US">tmp</span>中，然后在安全进入目标状态，这个过程我们并没有损失什么东西（代码清晰性，性能等等）。看上去，实现强保证并不比基本保证困难多少，一般而言，也确实如此。不过，别太自信，举一种典型的很难实现强保证的例子，对于区间操作的强保证：<span lang="EN-US"><o:p></o:p></span></p> <div style="border-right: #0099cc 1pt solid; padding-right: 4pt; border-top: #0099cc 1pt solid; padding-left: 4pt; background: #ddedfb; padding-bottom: 4pt; margin-left: 3.75pt; border-left: #0099cc 1pt solid; margin-right: 3.75pt; padding-top: 4pt; border-bottom: #0099cc 1pt solid; mso-element: para-border-div; mso-border-alt: solid #0099cc .75pt"> <p class="code" style="text-justify: inter-ideograph; background: #ddedfb; margin: 3.75pt 0cm; text-align: justify"><span lang="EN-US" style="font-size: 12pt; color: windowtext; font-family: 宋体">for (itr = range.begin(); itr != range.end(); ++itr){<br>&nbsp;&nbsp;&nbsp; itr-&gt;do_something();<br>}<o:p></o:p></span></p></div> <p style="text-justify: inter-ideograph; line-height: 150%; text-align: justify">　　如果某个<span lang="EN-US">do_something</span>失败了，<span lang="EN-US">range</span>将处于什么状态？这段代码仍然做到了基本保证，但不是强保证的，根据实现强保证的基本原则，我们可以这么做：<span lang="EN-US"><o:p></o:p></span></p> <div style="border-right: #0099cc 1pt solid; padding-right: 4pt; border-top: #0099cc 1pt solid; padding-left: 4pt; background: #ddedfb; padding-bottom: 4pt; margin-left: 3.75pt; border-left: #0099cc 1pt solid; margin-right: 3.75pt; padding-top: 4pt; border-bottom: #0099cc 1pt solid; mso-element: para-border-div; mso-border-alt: solid #0099cc .75pt"> <p class="code" style="text-justify: inter-ideograph; background: #ddedfb; margin: 3.75pt 0cm; text-align: justify"><span lang="EN-US" style="font-size: 12pt; color: windowtext; font-family: 宋体">tmp = range;<br>for (itr = tmp.begin(); itr != tmp.end(); ++itr){<br>&nbsp;&nbsp;&nbsp; itr-&gt;do_something();<br>}<br>swap(tmp, range);<o:p></o:p></span></p></div> <p style="text-justify: inter-ideograph; line-height: 150%; text-align: justify">　　似乎很简单啊！呵呵，这样的做法并非不可取，只是有时候行不通。因为我们额外付出了性能的代价，而且，这个代价可能很大。无论如何，我们阐述了实现强保证的方法，怎么取舍则由您决定了。<span lang="EN-US"><o:p></o:p></span></p> <p style="text-justify: inter-ideograph; line-height: 150%; text-align: justify">　　接下来讨论最后一种异常安全保证：不会失败。<span lang="EN-US"><o:p></o:p></span></p> <p style="text-justify: inter-ideograph; line-height: 150%; text-align: justify">　　通常，我们并不需要这么强的安全保证，但是我们至少必须保证三类过程不会失败：析构函数，释放类函数，<span lang="EN-US">swap</span>。析构和释放函数不会失败，这是<span lang="EN-US">RAII</span>技术有效的基石，<span lang="EN-US">swap</span>不会失败，是为了<span lang="EN-US">“</span>在决不失败的过程中，把对象替换到目标状态<span lang="EN-US">”</span>。我们前面的所有讨论都是建立在这三类过程不会失败的基础上的，在这里，弥补了上面的那个疏漏。<span lang="EN-US"><o:p></o:p></span></p> <p style="text-justify: inter-ideograph; line-height: 150%; text-align: justify">　　一般而言，语言内部类型的赋值、取地址等运算是不会发生异常的，上述三类过程逻辑上也是不会发生异常的。内部运算中，除法运算可能抛出异常。但是地址访问错通常是一种错误，而不是异常，我们本应该在前条件检查中就发现的这一点的。所有不会发生异常操作的简单累加，仍然不会导致异常。<span lang="EN-US"><o:p></o:p></span></p> <p style="text-justify: inter-ideograph; line-height: 150%; text-align: justify">　　好了，现在我们可以总结一下编写异常安全代码的几条准则了：<span lang="EN-US"><o:p></o:p></span></p> <p style="text-justify: inter-ideograph; line-height: 150%; text-align: justify">　　<span lang="EN-US">1.</span>只在应该使用异常的地方抛出异常<span lang="EN-US"><br></span>　　<span lang="EN-US">2.</span>如果不知道如何处理异常，请不要捕获<span lang="EN-US">(</span>截留<span lang="EN-US">)</span>异常。<span lang="EN-US"><br></span>　　<span lang="EN-US">3.</span>充分使用<span lang="EN-US">RAII</span>，旁路异常。<span lang="EN-US"><br></span>　　<span lang="EN-US">4.</span>努力实现强保证，至少实现基本保证。<span lang="EN-US"><br></span>　　<span lang="EN-US">5.</span>确保析构函数、释放类函数和<span lang="EN-US">swap</span>不会失败。<span lang="EN-US"><o:p></o:p></span></p> <p style="text-justify: inter-ideograph; line-height: 150%; text-align: justify">　　另外，还有一些语言细节问题，因为和这个主题有关也一并列出：<span lang="EN-US"><o:p></o:p></span></p> <p style="text-justify: inter-ideograph; line-height: 150%; text-align: justify">　　<span lang="EN-US">1.</span>不要这样抛出异常：<span lang="EN-US">throw new exception;</span>这将导致内存泄漏。<span lang="EN-US"><br></span>　　<span lang="EN-US">2.</span>自定义类型，应该捕获异常的引用类型：<span lang="EN-US">catch(exception&amp; e)</span>或<span lang="EN-US">catch(const exception&amp; e)</span>。<span lang="EN-US"><br></span>　　<span lang="EN-US">3.</span>不要使用异常规范，即使是空异常规范。编译器并不保证只抛出异常规范允许的异常，更多内容请参考相关书籍。<span lang="EN-US"><o:p></o:p></span></p> <p class="MsoNormal"><span lang="EN-US" style="font-size: 12pt; font-family: 宋体; mso-bidi-font-family: arial"><o:p>&nbsp;</o:p></span></p><img src ="http://www.cppblog.com/woaidongmao/aggbug/70475.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/woaidongmao/" target="_blank">肥仔</a> 2008-12-26 23:06 <a href="http://www.cppblog.com/woaidongmao/archive/2008/12/26/70475.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>typedef使用大全</title><link>http://www.cppblog.com/woaidongmao/archive/2008/12/17/69657.html</link><dc:creator>肥仔</dc:creator><author>肥仔</author><pubDate>Wed, 17 Dec 2008 09:07:00 GMT</pubDate><guid>http://www.cppblog.com/woaidongmao/archive/2008/12/17/69657.html</guid><wfw:comment>http://www.cppblog.com/woaidongmao/comments/69657.html</wfw:comment><comments>http://www.cppblog.com/woaidongmao/archive/2008/12/17/69657.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/woaidongmao/comments/commentRss/69657.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/woaidongmao/services/trackbacks/69657.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: typedef到处都是，但是能够真正懂得typedef使用的不算太多。对于初学者而言，看别人的源码时对到处充斥的typedef往往不知所错，而参考书又很少，所以在此给出一个源码，供大家参考 &nbsp; #include &lt;stdio.h&gt; #include &lt;iostream.h&gt; &nbsp; &nbsp; /* 避免Visual C的for与标准for的不同 */ #...&nbsp;&nbsp;<a href='http://www.cppblog.com/woaidongmao/archive/2008/12/17/69657.html'>阅读全文</a><img src ="http://www.cppblog.com/woaidongmao/aggbug/69657.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/woaidongmao/" target="_blank">肥仔</a> 2008-12-17 17:07 <a href="http://www.cppblog.com/woaidongmao/archive/2008/12/17/69657.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>if和switch效率的再研究</title><link>http://www.cppblog.com/woaidongmao/archive/2008/12/17/69654.html</link><dc:creator>肥仔</dc:creator><author>肥仔</author><pubDate>Wed, 17 Dec 2008 08:47:00 GMT</pubDate><guid>http://www.cppblog.com/woaidongmao/archive/2008/12/17/69654.html</guid><wfw:comment>http://www.cppblog.com/woaidongmao/comments/69654.html</wfw:comment><comments>http://www.cppblog.com/woaidongmao/archive/2008/12/17/69654.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/woaidongmao/comments/commentRss/69654.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/woaidongmao/services/trackbacks/69654.html</trackback:ping><description><![CDATA[<p class="MsoNormal" style="background: #f7fbfe; line-height: 150%; text-align: left; mso-pagination: widow-orphan" align="left"><span style="font-size: 12pt; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: tahoma; mso-font-kerning: 0pt">昨天发现了一本叫做<span lang="EN-US">CSAPP</span>的书，终于找到了关于<span lang="EN-US">switch</span>问题的解答。<span lang="EN-US"><br></span>这是一段<span lang="EN-US">C</span>代码：<span lang="EN-US"><br><br><br></span>用<span lang="EN-US">GCC</span>汇编出来的代码如下： <span lang="EN-US"><?xml:namespace prefix = o /><o:p></o:p></span></span></p> <p class="MsoNormal" style="background: #f7fbfe; margin: 12pt 12pt 0pt; text-indent: 24pt; line-height: 150%; text-align: left; mso-pagination: widow-orphan" align="left"><b><span lang="EN-US" style="font-size: 12pt; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: tahoma; mso-font-kerning: 0pt">CODE:<o:p></o:p></span></b></p> <p class="MsoNormal" style="line-height: 150%"><span lang="EN-US" style="font-size: 12pt; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">&nbsp;&nbsp;&nbsp; .file&nbsp;&nbsp;&nbsp; "switch.c"<span style="border-right: #cccccc 1pt solid; padding-right: 6pt; border-top: #cccccc 1pt solid; padding-left: 6pt; padding-bottom: 6pt; border-left: #cccccc 1pt solid; padding-top: 6pt; border-bottom: #cccccc 1pt solid; mso-border-alt: solid #cccccc .75pt"><br></span>&nbsp;&nbsp;&nbsp; .version&nbsp;&nbsp;&nbsp; "01.01"<span style="border-right: #cccccc 1pt solid; padding-right: 6pt; border-top: #cccccc 1pt solid; padding-left: 6pt; padding-bottom: 6pt; border-left: #cccccc 1pt solid; padding-top: 6pt; border-bottom: #cccccc 1pt solid; mso-border-alt: solid #cccccc .75pt"><br></span>gcc2_compiled.:<span style="border-right: #cccccc 1pt solid; padding-right: 6pt; border-top: #cccccc 1pt solid; padding-left: 6pt; padding-bottom: 6pt; border-left: #cccccc 1pt solid; padding-top: 6pt; border-bottom: #cccccc 1pt solid; mso-border-alt: solid #cccccc .75pt"><br></span>.text<span style="border-right: #cccccc 1pt solid; padding-right: 6pt; border-top: #cccccc 1pt solid; padding-left: 6pt; padding-bottom: 6pt; border-left: #cccccc 1pt solid; padding-top: 6pt; border-bottom: #cccccc 1pt solid; mso-border-alt: solid #cccccc .75pt"><br></span>&nbsp;&nbsp;&nbsp; .align 4<span style="border-right: #cccccc 1pt solid; padding-right: 6pt; border-top: #cccccc 1pt solid; padding-left: 6pt; padding-bottom: 6pt; border-left: #cccccc 1pt solid; padding-top: 6pt; border-bottom: #cccccc 1pt solid; mso-border-alt: solid #cccccc .75pt"><br></span>.globl switch_eg<span style="border-right: #cccccc 1pt solid; padding-right: 6pt; border-top: #cccccc 1pt solid; padding-left: 6pt; padding-bottom: 6pt; border-left: #cccccc 1pt solid; padding-top: 6pt; border-bottom: #cccccc 1pt solid; mso-border-alt: solid #cccccc .75pt"><br></span>&nbsp;&nbsp;&nbsp; .type&nbsp;&nbsp;&nbsp;&nbsp; switch_eg,@function<span style="border-right: #cccccc 1pt solid; padding-right: 6pt; border-top: #cccccc 1pt solid; padding-left: 6pt; padding-bottom: 6pt; border-left: #cccccc 1pt solid; padding-top: 6pt; border-bottom: #cccccc 1pt solid; mso-border-alt: solid #cccccc .75pt"><br></span>switch_eg:<span style="border-right: #cccccc 1pt solid; padding-right: 6pt; border-top: #cccccc 1pt solid; padding-left: 6pt; padding-bottom: 6pt; border-left: #cccccc 1pt solid; padding-top: 6pt; border-bottom: #cccccc 1pt solid; mso-border-alt: solid #cccccc .75pt"><br></span>&nbsp;&nbsp;&nbsp; pushl %ebp<span style="border-right: #cccccc 1pt solid; padding-right: 6pt; border-top: #cccccc 1pt solid; padding-left: 6pt; padding-bottom: 6pt; border-left: #cccccc 1pt solid; padding-top: 6pt; border-bottom: #cccccc 1pt solid; mso-border-alt: solid #cccccc .75pt"><br></span>&nbsp;&nbsp;&nbsp; movl %esp,%ebp<span style="border-right: #cccccc 1pt solid; padding-right: 6pt; border-top: #cccccc 1pt solid; padding-left: 6pt; padding-bottom: 6pt; border-left: #cccccc 1pt solid; padding-top: 6pt; border-bottom: #cccccc 1pt solid; mso-border-alt: solid #cccccc .75pt"><br></span>&nbsp;&nbsp;&nbsp; movl 8(%ebp),%edx<span style="border-right: #cccccc 1pt solid; padding-right: 6pt; border-top: #cccccc 1pt solid; padding-left: 6pt; padding-bottom: 6pt; border-left: #cccccc 1pt solid; padding-top: 6pt; border-bottom: #cccccc 1pt solid; mso-border-alt: solid #cccccc .75pt"><br></span>&nbsp;&nbsp;&nbsp; leal -100(%edx),%eax<span style="border-right: #cccccc 1pt solid; padding-right: 6pt; border-top: #cccccc 1pt solid; padding-left: 6pt; padding-bottom: 6pt; border-left: #cccccc 1pt solid; padding-top: 6pt; border-bottom: #cccccc 1pt solid; mso-border-alt: solid #cccccc .75pt"><br></span>&nbsp;&nbsp;&nbsp; cmpl ,%eax<span style="border-right: #cccccc 1pt solid; padding-right: 6pt; border-top: #cccccc 1pt solid; padding-left: 6pt; padding-bottom: 6pt; border-left: #cccccc 1pt solid; padding-top: 6pt; border-bottom: #cccccc 1pt solid; mso-border-alt: solid #cccccc .75pt"><br></span>&nbsp;&nbsp;&nbsp; ja .L9<span style="border-right: #cccccc 1pt solid; padding-right: 6pt; border-top: #cccccc 1pt solid; padding-left: 6pt; padding-bottom: 6pt; border-left: #cccccc 1pt solid; padding-top: 6pt; border-bottom: #cccccc 1pt solid; mso-border-alt: solid #cccccc .75pt"><br></span>&nbsp;&nbsp;&nbsp; jmp *.L10(,%eax,4)<span style="border-right: #cccccc 1pt solid; padding-right: 6pt; border-top: #cccccc 1pt solid; padding-left: 6pt; padding-bottom: 6pt; border-left: #cccccc 1pt solid; padding-top: 6pt; border-bottom: #cccccc 1pt solid; mso-border-alt: solid #cccccc .75pt"><br></span>&nbsp;&nbsp;&nbsp; .p2align 4,,7<span style="border-right: #cccccc 1pt solid; padding-right: 6pt; border-top: #cccccc 1pt solid; padding-left: 6pt; padding-bottom: 6pt; border-left: #cccccc 1pt solid; padding-top: 6pt; border-bottom: #cccccc 1pt solid; mso-border-alt: solid #cccccc .75pt"><br></span>.section&nbsp;&nbsp;&nbsp; .rodata<span style="border-right: #cccccc 1pt solid; padding-right: 6pt; border-top: #cccccc 1pt solid; padding-left: 6pt; padding-bottom: 6pt; border-left: #cccccc 1pt solid; padding-top: 6pt; border-bottom: #cccccc 1pt solid; mso-border-alt: solid #cccccc .75pt"><br></span>&nbsp;&nbsp;&nbsp; .align 4<span style="border-right: #cccccc 1pt solid; padding-right: 6pt; border-top: #cccccc 1pt solid; padding-left: 6pt; padding-bottom: 6pt; border-left: #cccccc 1pt solid; padding-top: 6pt; border-bottom: #cccccc 1pt solid; mso-border-alt: solid #cccccc .75pt"><br></span>&nbsp;&nbsp;&nbsp; .align 4<span style="border-right: #cccccc 1pt solid; padding-right: 6pt; border-top: #cccccc 1pt solid; padding-left: 6pt; padding-bottom: 6pt; border-left: #cccccc 1pt solid; padding-top: 6pt; border-bottom: #cccccc 1pt solid; mso-border-alt: solid #cccccc .75pt"><br></span>.L10:<span style="border-right: #cccccc 1pt solid; padding-right: 6pt; border-top: #cccccc 1pt solid; padding-left: 6pt; padding-bottom: 6pt; border-left: #cccccc 1pt solid; padding-top: 6pt; border-bottom: #cccccc 1pt solid; mso-border-alt: solid #cccccc .75pt"><br></span>&nbsp;&nbsp;&nbsp; .long .L4<span style="border-right: #cccccc 1pt solid; padding-right: 6pt; border-top: #cccccc 1pt solid; padding-left: 6pt; padding-bottom: 6pt; border-left: #cccccc 1pt solid; padding-top: 6pt; border-bottom: #cccccc 1pt solid; mso-border-alt: solid #cccccc .75pt"><br></span>&nbsp;&nbsp;&nbsp; .long .L9<span style="border-right: #cccccc 1pt solid; padding-right: 6pt; border-top: #cccccc 1pt solid; padding-left: 6pt; padding-bottom: 6pt; border-left: #cccccc 1pt solid; padding-top: 6pt; border-bottom: #cccccc 1pt solid; mso-border-alt: solid #cccccc .75pt"><br></span>&nbsp;&nbsp;&nbsp; .long .L5<span style="border-right: #cccccc 1pt solid; padding-right: 6pt; border-top: #cccccc 1pt solid; padding-left: 6pt; padding-bottom: 6pt; border-left: #cccccc 1pt solid; padding-top: 6pt; border-bottom: #cccccc 1pt solid; mso-border-alt: solid #cccccc .75pt"><br></span>&nbsp;&nbsp;&nbsp; .long .L6<span style="border-right: #cccccc 1pt solid; padding-right: 6pt; border-top: #cccccc 1pt solid; padding-left: 6pt; padding-bottom: 6pt; border-left: #cccccc 1pt solid; padding-top: 6pt; border-bottom: #cccccc 1pt solid; mso-border-alt: solid #cccccc .75pt"><br></span>&nbsp;&nbsp;&nbsp; .long .L8<span style="border-right: #cccccc 1pt solid; padding-right: 6pt; border-top: #cccccc 1pt solid; padding-left: 6pt; padding-bottom: 6pt; border-left: #cccccc 1pt solid; padding-top: 6pt; border-bottom: #cccccc 1pt solid; mso-border-alt: solid #cccccc .75pt"><br></span>&nbsp;&nbsp;&nbsp; .long .L9<span style="border-right: #cccccc 1pt solid; padding-right: 6pt; border-top: #cccccc 1pt solid; padding-left: 6pt; padding-bottom: 6pt; border-left: #cccccc 1pt solid; padding-top: 6pt; border-bottom: #cccccc 1pt solid; mso-border-alt: solid #cccccc .75pt"><br></span>&nbsp;&nbsp;&nbsp; .long .L8<span style="border-right: #cccccc 1pt solid; padding-right: 6pt; border-top: #cccccc 1pt solid; padding-left: 6pt; padding-bottom: 6pt; border-left: #cccccc 1pt solid; padding-top: 6pt; border-bottom: #cccccc 1pt solid; mso-border-alt: solid #cccccc .75pt"><br></span>.text<span style="border-right: #cccccc 1pt solid; padding-right: 6pt; border-top: #cccccc 1pt solid; padding-left: 6pt; padding-bottom: 6pt; border-left: #cccccc 1pt solid; padding-top: 6pt; border-bottom: #cccccc 1pt solid; mso-border-alt: solid #cccccc .75pt"><br></span>&nbsp;&nbsp;&nbsp; .p2align 4,,7<span style="border-right: #cccccc 1pt solid; padding-right: 6pt; border-top: #cccccc 1pt solid; padding-left: 6pt; padding-bottom: 6pt; border-left: #cccccc 1pt solid; padding-top: 6pt; border-bottom: #cccccc 1pt solid; mso-border-alt: solid #cccccc .75pt"><br></span>.L4:<span style="border-right: #cccccc 1pt solid; padding-right: 6pt; border-top: #cccccc 1pt solid; padding-left: 6pt; padding-bottom: 6pt; border-left: #cccccc 1pt solid; padding-top: 6pt; border-bottom: #cccccc 1pt solid; mso-border-alt: solid #cccccc .75pt"><br></span>&nbsp;&nbsp;&nbsp; leal (%edx,%edx,2),%eax<span style="border-right: #cccccc 1pt solid; padding-right: 6pt; border-top: #cccccc 1pt solid; padding-left: 6pt; padding-bottom: 6pt; border-left: #cccccc 1pt solid; padding-top: 6pt; border-bottom: #cccccc 1pt solid; mso-border-alt: solid #cccccc .75pt"><br></span>&nbsp;&nbsp;&nbsp; leal (%edx,%eax,4),%edx<span style="border-right: #cccccc 1pt solid; padding-right: 6pt; border-top: #cccccc 1pt solid; padding-left: 6pt; padding-bottom: 6pt; border-left: #cccccc 1pt solid; padding-top: 6pt; border-bottom: #cccccc 1pt solid; mso-border-alt: solid #cccccc .75pt"><br></span>&nbsp;&nbsp;&nbsp; jmp .L3<span style="border-right: #cccccc 1pt solid; padding-right: 6pt; border-top: #cccccc 1pt solid; padding-left: 6pt; padding-bottom: 6pt; border-left: #cccccc 1pt solid; padding-top: 6pt; border-bottom: #cccccc 1pt solid; mso-border-alt: solid #cccccc .75pt"><br></span>&nbsp;&nbsp;&nbsp; .p2align 4,,7<span style="border-right: #cccccc 1pt solid; padding-right: 6pt; border-top: #cccccc 1pt solid; padding-left: 6pt; padding-bottom: 6pt; border-left: #cccccc 1pt solid; padding-top: 6pt; border-bottom: #cccccc 1pt solid; mso-border-alt: solid #cccccc .75pt"><br></span>.L5:<span style="border-right: #cccccc 1pt solid; padding-right: 6pt; border-top: #cccccc 1pt solid; padding-left: 6pt; padding-bottom: 6pt; border-left: #cccccc 1pt solid; padding-top: 6pt; border-bottom: #cccccc 1pt solid; mso-border-alt: solid #cccccc .75pt"><br></span>&nbsp;&nbsp;&nbsp; addl ,%edx<span style="border-right: #cccccc 1pt solid; padding-right: 6pt; border-top: #cccccc 1pt solid; padding-left: 6pt; padding-bottom: 6pt; border-left: #cccccc 1pt solid; padding-top: 6pt; border-bottom: #cccccc 1pt solid; mso-border-alt: solid #cccccc .75pt"><br></span>.L6:<span style="border-right: #cccccc 1pt solid; padding-right: 6pt; border-top: #cccccc 1pt solid; padding-left: 6pt; padding-bottom: 6pt; border-left: #cccccc 1pt solid; padding-top: 6pt; border-bottom: #cccccc 1pt solid; mso-border-alt: solid #cccccc .75pt"><br></span>&nbsp;&nbsp;&nbsp; addl ,%edx<span style="border-right: #cccccc 1pt solid; padding-right: 6pt; border-top: #cccccc 1pt solid; padding-left: 6pt; padding-bottom: 6pt; border-left: #cccccc 1pt solid; padding-top: 6pt; border-bottom: #cccccc 1pt solid; mso-border-alt: solid #cccccc .75pt"><br></span>&nbsp;&nbsp;&nbsp; jmp .L3<span style="border-right: #cccccc 1pt solid; padding-right: 6pt; border-top: #cccccc 1pt solid; padding-left: 6pt; padding-bottom: 6pt; border-left: #cccccc 1pt solid; padding-top: 6pt; border-bottom: #cccccc 1pt solid; mso-border-alt: solid #cccccc .75pt"><br></span>&nbsp;&nbsp;&nbsp; .p2align 4,,7<span style="border-right: #cccccc 1pt solid; padding-right: 6pt; border-top: #cccccc 1pt solid; padding-left: 6pt; padding-bottom: 6pt; border-left: #cccccc 1pt solid; padding-top: 6pt; border-bottom: #cccccc 1pt solid; mso-border-alt: solid #cccccc .75pt"><br></span>.L8:<span style="border-right: #cccccc 1pt solid; padding-right: 6pt; border-top: #cccccc 1pt solid; padding-left: 6pt; padding-bottom: 6pt; border-left: #cccccc 1pt solid; padding-top: 6pt; border-bottom: #cccccc 1pt solid; mso-border-alt: solid #cccccc .75pt"><br></span>&nbsp;&nbsp;&nbsp; imull %edx,%edx<span style="border-right: #cccccc 1pt solid; padding-right: 6pt; border-top: #cccccc 1pt solid; padding-left: 6pt; padding-bottom: 6pt; border-left: #cccccc 1pt solid; padding-top: 6pt; border-bottom: #cccccc 1pt solid; mso-border-alt: solid #cccccc .75pt"><br></span>&nbsp;&nbsp;&nbsp; jmp .L3<span style="border-right: #cccccc 1pt solid; padding-right: 6pt; border-top: #cccccc 1pt solid; padding-left: 6pt; padding-bottom: 6pt; border-left: #cccccc 1pt solid; padding-top: 6pt; border-bottom: #cccccc 1pt solid; mso-border-alt: solid #cccccc .75pt"><br></span>&nbsp;&nbsp;&nbsp; .p2align 4,,7<span style="border-right: #cccccc 1pt solid; padding-right: 6pt; border-top: #cccccc 1pt solid; padding-left: 6pt; padding-bottom: 6pt; border-left: #cccccc 1pt solid; padding-top: 6pt; border-bottom: #cccccc 1pt solid; mso-border-alt: solid #cccccc .75pt"><br></span>.L9:<span style="border-right: #cccccc 1pt solid; padding-right: 6pt; border-top: #cccccc 1pt solid; padding-left: 6pt; padding-bottom: 6pt; border-left: #cccccc 1pt solid; padding-top: 6pt; border-bottom: #cccccc 1pt solid; mso-border-alt: solid #cccccc .75pt"><br></span>&nbsp;&nbsp;&nbsp; xorl %edx,%edx<span style="border-right: #cccccc 1pt solid; padding-right: 6pt; border-top: #cccccc 1pt solid; padding-left: 6pt; padding-bottom: 6pt; border-left: #cccccc 1pt solid; padding-top: 6pt; border-bottom: #cccccc 1pt solid; mso-border-alt: solid #cccccc .75pt"><br></span>.L3:<span style="border-right: #cccccc 1pt solid; padding-right: 6pt; border-top: #cccccc 1pt solid; padding-left: 6pt; padding-bottom: 6pt; border-left: #cccccc 1pt solid; padding-top: 6pt; border-bottom: #cccccc 1pt solid; mso-border-alt: solid #cccccc .75pt"><br></span>&nbsp;&nbsp;&nbsp; movl %edx,%eax<span style="border-right: #cccccc 1pt solid; padding-right: 6pt; border-top: #cccccc 1pt solid; padding-left: 6pt; padding-bottom: 6pt; border-left: #cccccc 1pt solid; padding-top: 6pt; border-bottom: #cccccc 1pt solid; mso-border-alt: solid #cccccc .75pt"><br></span>&nbsp;&nbsp;&nbsp; movl %ebp,%esp<span style="border-right: #cccccc 1pt solid; padding-right: 6pt; border-top: #cccccc 1pt solid; padding-left: 6pt; padding-bottom: 6pt; border-left: #cccccc 1pt solid; padding-top: 6pt; border-bottom: #cccccc 1pt solid; mso-border-alt: solid #cccccc .75pt"><br></span>&nbsp;&nbsp;&nbsp; popl %ebp<span style="border-right: #cccccc 1pt solid; padding-right: 6pt; border-top: #cccccc 1pt solid; padding-left: 6pt; padding-bottom: 6pt; border-left: #cccccc 1pt solid; padding-top: 6pt; border-bottom: #cccccc 1pt solid; mso-border-alt: solid #cccccc .75pt"><br></span>&nbsp;&nbsp;&nbsp; ret<span style="border-right: #cccccc 1pt solid; padding-right: 6pt; border-top: #cccccc 1pt solid; padding-left: 6pt; padding-bottom: 6pt; border-left: #cccccc 1pt solid; padding-top: 6pt; border-bottom: #cccccc 1pt solid; mso-border-alt: solid #cccccc .75pt"><br></span>.Lfe1:<span style="border-right: #cccccc 1pt solid; padding-right: 6pt; border-top: #cccccc 1pt solid; padding-left: 6pt; padding-bottom: 6pt; border-left: #cccccc 1pt solid; padding-top: 6pt; border-bottom: #cccccc 1pt solid; mso-border-alt: solid #cccccc .75pt"><br></span>&nbsp;&nbsp;&nbsp; .size&nbsp;&nbsp;&nbsp;&nbsp; switch_eg,.Lfe1-switch_eg<span style="border-right: #cccccc 1pt solid; padding-right: 6pt; border-top: #cccccc 1pt solid; padding-left: 6pt; padding-bottom: 6pt; border-left: #cccccc 1pt solid; padding-top: 6pt; border-bottom: #cccccc 1pt solid; mso-border-alt: solid #cccccc .75pt"><br></span>&nbsp;&nbsp;&nbsp; .ident&nbsp;&nbsp;&nbsp; "GCC: (GNU) 2.95.3 20010315 (release)"</span><span style="font-size: 12pt; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: tahoma; mso-font-kerning: 0pt">在上面的汇编代码中我们可以很清楚的看到<span lang="EN-US">switch</span>部分被分配了一个连续的查找表，<span lang="EN-US">switch case</span>中不连续的部分也被添加上了相应的条目，<span lang="EN-US">switch</span>表的大小不是根据<span lang="EN-US">case</span>语句的多少，而是<span lang="EN-US">case</span>的最大值的最小值之间的间距。在选择相应 的分支时，会先有一个<span lang="EN-US">cmp</span>子句，如果大于查找表的最大值，则跳转到<span lang="EN-US">default</span>子句。而其他所有的<span lang="EN-US">case</span>语句的耗时都回事<span lang="EN-US">O(1)</span>。<span lang="EN-US"><br><br></span>相比于<span lang="EN-US">if-else</span>结构，<span lang="EN-US">switch</span>的效率绝对是要高很多的，但是<span lang="EN-US">switch</span>使用查找表的方式决定了<span lang="EN-US">case</span>的条件必须是一个连续的常量。而<span lang="EN-US">if-else</span>则可以灵活的多。</span><span lang="EN-US" style="font-size: 12pt; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial"><o:p></o:p></span></p><img src ="http://www.cppblog.com/woaidongmao/aggbug/69654.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/woaidongmao/" target="_blank">肥仔</a> 2008-12-17 16:47 <a href="http://www.cppblog.com/woaidongmao/archive/2008/12/17/69654.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>struct中可不可以有const的量呢</title><link>http://www.cppblog.com/woaidongmao/archive/2008/12/17/69653.html</link><dc:creator>肥仔</dc:creator><author>肥仔</author><pubDate>Wed, 17 Dec 2008 08:41:00 GMT</pubDate><guid>http://www.cppblog.com/woaidongmao/archive/2008/12/17/69653.html</guid><wfw:comment>http://www.cppblog.com/woaidongmao/comments/69653.html</wfw:comment><comments>http://www.cppblog.com/woaidongmao/archive/2008/12/17/69653.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/woaidongmao/comments/commentRss/69653.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/woaidongmao/services/trackbacks/69653.html</trackback:ping><description><![CDATA[<p class="MsoNormal" style="line-height: 150%"><span lang="EN-US" style="color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: tahoma">const </span><span style="color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: tahoma">修饰一个变量时，编译器认为这个变量是一个不可修改的，但是他和其他变量一样具有存储空间，如果使用强制转换，同样可以被访问，例如：<span lang="EN-US"> <br>const int i=3; <br>(*(int*)&amp;i)=4; <br></span>结果<span lang="EN-US">i</span>的值为<span lang="EN-US">4</span>。<span lang="EN-US"> <br></span>这就是说，在<span lang="EN-US">C/C++</span>中，<span lang="EN-US">const</span>修饰的变量必须在声明时给予一个特定值，在以后过程中永不修改<span lang="EN-US">,</span>初始化的值可以是一个常数，也可以是一个变量或者表达式，例如<span lang="EN-US"> <br>const int i=3; <br>const int j=argc; <br>const int k=argc*i; <br><br></span>无论是在<span lang="EN-US">C</span>还是在<span lang="EN-US">C++</span>语言中，<span lang="EN-US">struct</span>结构都是可以包含<span lang="EN-US">const</span>成员变量的。<span lang="EN-US"> <br>const</span>成员变量可以在声明的时初始化，也可以不初始化，但是声明后，<span lang="EN-US">const</span>变量就不能访问了。<span lang="EN-US"> <br></span>例如，在<span lang="EN-US">C</span>语言中（<span lang="EN-US">TC2.0</span>）<span lang="EN-US"> <br>struct TYPE{ <br>&nbsp; const int a; <br>&nbsp; int b; <br>}; <br></span>那么以下的操作都是合法的<span lang="EN-US"> <br>struct TYPE t={1,2}; <br>struct TYPE t={1}; <br>struct TYPE t; <br></span>这是符合<span lang="EN-US">const</span>的基本定义的：只能在声明时初始化，其他时间都不能访问这一点。<span lang="EN-US"> <br></span>对于<span lang="EN-US">C++</span>语言，则可以在构造函数的初始化化列表中：<span lang="EN-US"> <br>struct TYPE{ <br>&nbsp;&nbsp; const int a; <br>&nbsp;&nbsp; int b; <br>&nbsp;&nbsp; TYPE(int aval):a(aval){} <br>}; <br></span>注意：只能在初始化参数列表中，这种形式就是错误的：<span lang="EN-US"> <br>TYPE(int aval){ a=aval;} <br></span>对于<span lang="EN-US">C++</span>编译器，他只认为，在初始化列表中显示的初始化才是符合<span lang="EN-US">const</span>精神的。</span><span lang="EN-US" style="color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: arial"><?xml:namespace prefix = o /><o:p></o:p></span></p><img src ="http://www.cppblog.com/woaidongmao/aggbug/69653.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/woaidongmao/" target="_blank">肥仔</a> 2008-12-17 16:41 <a href="http://www.cppblog.com/woaidongmao/archive/2008/12/17/69653.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>do...while(0)的妙用</title><link>http://www.cppblog.com/woaidongmao/archive/2008/12/17/69643.html</link><dc:creator>肥仔</dc:creator><author>肥仔</author><pubDate>Wed, 17 Dec 2008 04:30:00 GMT</pubDate><guid>http://www.cppblog.com/woaidongmao/archive/2008/12/17/69643.html</guid><wfw:comment>http://www.cppblog.com/woaidongmao/comments/69643.html</wfw:comment><comments>http://www.cppblog.com/woaidongmao/archive/2008/12/17/69643.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/woaidongmao/comments/commentRss/69643.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/woaidongmao/services/trackbacks/69643.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &nbsp;&nbsp;&nbsp; 在C++中，有三种类型的循环语句：for, while, 和do...while， 但是在一般应用中作循环时，我们可能用for和while要多一些，do...while相对不受重视。&nbsp;&nbsp;&nbsp; 但是，最近在读我们项目的代码时，却发现了do...while的一些十分聪明的用法，不是用来做循环，而是用作其他来提高代码的健壮性。 1. do...&nbsp;&nbsp;<a href='http://www.cppblog.com/woaidongmao/archive/2008/12/17/69643.html'>阅读全文</a><img src ="http://www.cppblog.com/woaidongmao/aggbug/69643.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/woaidongmao/" target="_blank">肥仔</a> 2008-12-17 12:30 <a href="http://www.cppblog.com/woaidongmao/archive/2008/12/17/69643.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>字符串匹配算法</title><link>http://www.cppblog.com/woaidongmao/archive/2008/12/14/69407.html</link><dc:creator>肥仔</dc:creator><author>肥仔</author><pubDate>Sun, 14 Dec 2008 09:22:00 GMT</pubDate><guid>http://www.cppblog.com/woaidongmao/archive/2008/12/14/69407.html</guid><wfw:comment>http://www.cppblog.com/woaidongmao/comments/69407.html</wfw:comment><comments>http://www.cppblog.com/woaidongmao/archive/2008/12/14/69407.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/woaidongmao/comments/commentRss/69407.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/woaidongmao/services/trackbacks/69407.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 一、简介 文本信息可以说是迄今为止最主要的一种信息交换手段，而作为文本处理中的一个重要领域——字符串匹配，就是我们今天要说的话题。（原文还特意提及文本数据数量每18个月翻一番，以此论证算法必须要是高效的。不过我注意到摩尔定律也是18个月翻番，这正说明数据的增长是紧紧跟随处理速度的，因此越是使用高效的算法，将来待处理的数据就会越多。这也提示屏幕前的各位，代码不要写得太快了……） &nbsp; 字符串...&nbsp;&nbsp;<a href='http://www.cppblog.com/woaidongmao/archive/2008/12/14/69407.html'>阅读全文</a><img src ="http://www.cppblog.com/woaidongmao/aggbug/69407.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/woaidongmao/" target="_blank">肥仔</a> 2008-12-14 17:22 <a href="http://www.cppblog.com/woaidongmao/archive/2008/12/14/69407.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>static 变量初始化顺序引发的bug</title><link>http://www.cppblog.com/woaidongmao/archive/2008/12/03/68512.html</link><dc:creator>肥仔</dc:creator><author>肥仔</author><pubDate>Wed, 03 Dec 2008 13:38:00 GMT</pubDate><guid>http://www.cppblog.com/woaidongmao/archive/2008/12/03/68512.html</guid><wfw:comment>http://www.cppblog.com/woaidongmao/comments/68512.html</wfw:comment><comments>http://www.cppblog.com/woaidongmao/archive/2008/12/03/68512.html#Feedback</comments><slash:comments>14</slash:comments><wfw:commentRss>http://www.cppblog.com/woaidongmao/comments/commentRss/68512.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/woaidongmao/services/trackbacks/68512.html</trackback:ping><description><![CDATA[<p></p> <p class="MsoNormal"><span lang="EN-US" style="font-family: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: arial">没想到会遇到这样的问题，</span></p> <p class="MsoNormal"><span lang="EN-US" style="font-family: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: arial">在VC6环境下测试，重点请看红色字体与图片。</span></p> <p class="MsoNormal"><span lang="EN-US" style="font-family: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: arial"></span>&nbsp;</p> <p class="MsoNormal"><span lang="EN-US" style="font-family: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: arial">#include "stdafx.h"<?xml:namespace prefix = o /><o:p></o:p></span></p> <p class="MsoNormal"><span lang="EN-US" style="font-family: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: arial">#include &lt;stdio.h&gt;<o:p></o:p></span></p> <p class="MsoNormal"><span lang="EN-US" style="font-family: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: arial"><o:p>&nbsp;</o:p></span></p> <p class="MsoNormal"><span lang="EN-US" style="font-family: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: arial">typedef struct sData <o:p></o:p></span></p> <p class="MsoNormal"><span lang="EN-US" style="font-family: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: arial">{<o:p></o:p></span></p> <p class="MsoNormal"><span lang="EN-US" style="font-family: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: arial"><span style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp; </span>static const char* text;<o:p></o:p></span></p> <p class="MsoNormal"><span lang="EN-US" style="font-family: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: arial"><span style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp; </span>static int<span style="mso-tab-count: 1">&nbsp; </span>val_a;<o:p></o:p></span></p> <p class="MsoNormal"><span lang="EN-US" style="font-family: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: arial"><span style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp; </span>static int<span style="mso-tab-count: 1">&nbsp; </span>val_b;<o:p></o:p></span></p> <p class="MsoNormal"><span lang="EN-US" style="font-family: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: arial">} sData, *Self_Ptr;<o:p></o:p></span></p> <p class="MsoNormal"><span lang="EN-US" style="font-family: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: arial"><o:p>&nbsp;</o:p></span></p> <p class="MsoNormal"><span lang="EN-US" style="font-family: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: arial">typedef struct<span style="mso-spacerun: yes">&nbsp; </span><o:p></o:p></span></p> <p class="MsoNormal"><span lang="EN-US" style="font-family: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: arial">{<o:p></o:p></span></p> <p class="MsoNormal"><span lang="EN-US" style="font-family: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: arial"><span style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp; </span>char* text;<o:p></o:p></span></p> <p class="MsoNormal"><span lang="EN-US" style="font-family: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: arial"><span style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp; </span>int<span style="mso-tab-count: 1"> </span>val_a;<o:p></o:p></span></p> <p class="MsoNormal"><span lang="EN-US" style="font-family: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: arial"><span style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp; </span>int<span style="mso-tab-count: 1"> </span>val_b;<o:p></o:p></span></p> <p class="MsoNormal"><span lang="EN-US" style="font-family: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: arial">}* Other_Ptr;<o:p></o:p></span></p> <p class="MsoNormal"><span lang="EN-US" style="font-family: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: arial"><o:p>&nbsp;</o:p></span></p> <p class="MsoNormal"><span lang="EN-US" style="font-family: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: arial"><o:p>&nbsp;</o:p></span></p> <p class="MsoNormal"><span lang="EN-US" style="font-family: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: arial">const char* sData::text = "this is a test string\0";<o:p></o:p></span></p> <p class="MsoNormal"><span lang="EN-US" style="font-family: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: arial">int<span style="mso-tab-count: 1"> </span><span style="mso-spacerun: yes">&nbsp; </span>sData::val_b = 200;<o:p></o:p></span></p> <p class="MsoNormal"><span lang="EN-US" style="font-family: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: arial">int<span style="mso-tab-count: 1"> </span><span style="mso-spacerun: yes">&nbsp; </span>sData::val_a = 100;<o:p></o:p></span></p> <p class="MsoNormal"><span lang="EN-US" style="font-family: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: arial"><o:p>&nbsp;</o:p></span></p> <p class="MsoNormal"><span lang="EN-US" style="font-family: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: arial">int main(int argc, char* argv[])<o:p></o:p></span></p> <p class="MsoNormal"><span lang="EN-US" style="font-family: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: arial">{<o:p></o:p></span></p> <p class="MsoNormal"><span lang="EN-US" style="font-family: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: arial"><span style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp; </span>Self_Ptr p_self = (Self_Ptr)&amp;(sData::text);<o:p></o:p></span></p> <p class="MsoNormal"><span lang="EN-US" style="font-family: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: arial"><span style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp; </span>Other_Ptr p_other = (Other_Ptr)&amp;(sData::text);<o:p></o:p></span></p> <p class="MsoNormal"><span lang="EN-US" style="font-family: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: arial"><span style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp; </span>printf("%d\n", sizeof(sData));<span style="mso-tab-count: 7">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>//----1, static</span><span style="font-family: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: arial">成员不计入<span lang="EN-US">sizeof<o:p></o:p></span></span></p> <p class="MsoNormal"><span lang="EN-US" style="font-family: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: arial"><span style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp; </span>printf("val_a: %d-%d\n", p_self-&gt;val_a, sData::val_a);<span style="mso-tab-count: 1">&nbsp; </span>//----val_a: 100-100<o:p></o:p></span></p> <p class="MsoNormal"><span lang="EN-US" style="font-family: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: arial"><span style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp; </span>printf("val_b: %d-%d\n", p_self-&gt;val_b, sData::val_b);<span style="mso-tab-count: 1">&nbsp; </span>//----val_b: 200-200<o:p></o:p></span></p> <p class="MsoNormal"><span lang="EN-US" style="font-family: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: arial"><span style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp; </span>printf("val_a: %d-%d\n", p_self-&gt;val_a, p_other-&gt;val_a);<span style="color: red">//----val_a: 100-200<o:p></o:p></span></span></p> <p class="MsoNormal"><span lang="EN-US" style="font-family: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: arial"><span style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp; </span>printf("val_b: %d-%d\n", p_self-&gt;val_b, p_other-&gt;val_b);<span style="color: red">//----val_b: 200-100</span><o:p></o:p></span></p> <p class="MsoNormal"><span lang="EN-US" style="font-family: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: arial"><span style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp; </span>return 0;<o:p></o:p></span></p> <p class="MsoNormal"><span lang="EN-US" style="font-family: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: arial">}<o:p></o:p></span></p> <p class="MsoNormal"><span lang="EN-US" style="font-family: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: arial"><o:p>&nbsp;</o:p></span></p> <p class="MsoNormal"><a href="http://www.cppblog.com/images/cppblog_com/woaidongmao/WindowsLiveWriter/092d43723407_12D92/image_2.png"><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="442" alt="image" src="http://www.cppblog.com/images/cppblog_com/woaidongmao/WindowsLiveWriter/092d43723407_12D92/image_thumb.png" width="673" border="0"></a></p><img src ="http://www.cppblog.com/woaidongmao/aggbug/68512.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/woaidongmao/" target="_blank">肥仔</a> 2008-12-03 21:38 <a href="http://www.cppblog.com/woaidongmao/archive/2008/12/03/68512.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>SIZEOF宏，弥补sizeof不足</title><link>http://www.cppblog.com/woaidongmao/archive/2008/11/28/68096.html</link><dc:creator>肥仔</dc:creator><author>肥仔</author><pubDate>Fri, 28 Nov 2008 10:56:00 GMT</pubDate><guid>http://www.cppblog.com/woaidongmao/archive/2008/11/28/68096.html</guid><wfw:comment>http://www.cppblog.com/woaidongmao/comments/68096.html</wfw:comment><comments>http://www.cppblog.com/woaidongmao/archive/2008/11/28/68096.html#Feedback</comments><slash:comments>17</slash:comments><wfw:commentRss>http://www.cppblog.com/woaidongmao/comments/commentRss/68096.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/woaidongmao/services/trackbacks/68096.html</trackback:ping><description><![CDATA[<p>&nbsp;</p> <p class="MsoNormal" style="line-height: 150%"><span style="line-height: 150%; font-family: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: arial">对<span lang="EN-US">POD<?xml:namespace prefix = o /><o:p></o:p></span></span></p> <p class="MsoNormal" style="line-height: 150%"><span lang="EN-US" style="line-height: 150%; font-family: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: arial">struct Data<o:p></o:p></span></p> <p class="MsoNormal" style="line-height: 150%"><span lang="EN-US" style="line-height: 150%; font-family: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: arial">{<o:p></o:p></span></p> <p class="MsoNormal" style="line-height: 150%"><span lang="EN-US" style="line-height: 150%; font-family: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: arial"><span style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp; i</span>nt a;<o:p></o:p></span></p> <p class="MsoNormal" style="line-height: 150%"><span lang="EN-US" style="line-height: 150%; font-family: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: arial"><span style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp; i</span>nt b[32];<o:p></o:p></span></p> <p class="MsoNormal" style="line-height: 150%"><span lang="EN-US" style="line-height: 150%; font-family: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: arial"><span style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp; </span>char c[128];<o:p></o:p></span></p> <p class="MsoNormal" style="line-height: 150%"><span lang="EN-US" style="line-height: 150%; font-family: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: arial">};<o:p></o:p></span></p> <p class="MsoNormal" style="line-height: 150%"><span lang="EN-US" style="line-height: 150%; font-family: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: arial">C/C++</span><span style="line-height: 150%; font-family: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: arial">不能够支持如下的语法：<span lang="EN-US">sizeof(Data::a); sizeof(Data::b); sizeof(Data::c[0]), sizeof</span>必须要有存在的对象，才可以进行操作<span lang="EN-US">,</span>这个不好<span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal" style="line-height: 150%"><span style="line-height: 150%; font-family: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: arial">仿照<span lang="EN-US">offsetof</span>宏，定义一个<span lang="EN-US">SIZEOF</span>宏：<span lang="EN-US">#define SIZEOF(s,m) sizeof(((s *)0)-&gt;m)<o:p></o:p></span></span></p> <p class="MsoNormal" style="line-height: 150%"><span style="line-height: 150%; font-family: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: arial">在<span lang="EN-US">VC6</span>下可以工作，其他环境不知<span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal" style="line-height: 150%"><span lang="EN-US" style="line-height: 150%; font-family: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: arial"><o:p>&nbsp;</o:p></span></p> <p class="MsoNormal" style="line-height: 150%"><span lang="EN-US" style="line-height: 150%; font-family: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: arial">#define SIZEOF(s,m) sizeof(((s *)0)-&gt;m)<o:p></o:p></span></p> <p class="MsoNormal" style="line-height: 150%"><span lang="EN-US" style="line-height: 150%; font-family: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: arial">struct Data<o:p></o:p></span></p> <p class="MsoNormal" style="line-height: 150%"><span lang="EN-US" style="line-height: 150%; font-family: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: arial">{<o:p></o:p></span></p> <p class="MsoNormal" style="line-height: 150%"><span lang="EN-US" style="line-height: 150%; font-family: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: arial"><span style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp; </span>int a;<o:p></o:p></span></p> <p class="MsoNormal" style="line-height: 150%"><span lang="EN-US" style="line-height: 150%; font-family: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: arial"><span style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp; </span>int<span style="mso-spacerun: yes">&nbsp; </span>b[32];<o:p></o:p></span></p> <p class="MsoNormal" style="line-height: 150%"><span lang="EN-US" style="line-height: 150%; font-family: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: arial"><span style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp; </span>char c[128];<o:p></o:p></span></p> <p class="MsoNormal" style="line-height: 150%"><span lang="EN-US" style="line-height: 150%; font-family: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: arial">};<o:p></o:p></span></p> <p class="MsoNormal" style="line-height: 150%"><span lang="EN-US" style="line-height: 150%; font-family: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: arial"><o:p>&nbsp;</o:p></span></p> <p class="MsoNormal" style="line-height: 150%"><span lang="EN-US" style="line-height: 150%; font-family: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: arial">int main(int argc, char* argv[])<o:p></o:p></span></p> <p class="MsoNormal" style="line-height: 150%"><span lang="EN-US" style="line-height: 150%; font-family: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: arial">{<o:p></o:p></span></p> <p class="MsoNormal" style="line-height: 150%"><span lang="EN-US" style="line-height: 150%; font-family: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: arial"><span style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp; </span>int z = 0;<o:p></o:p></span></p> <p class="MsoNormal" style="line-height: 150%"><span lang="EN-US" style="line-height: 150%; font-family: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: arial"><span style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp; z = </span>SIZEOF(Data, a);<span style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp; </span>//---- 4<o:p></o:p></span></p> <p class="MsoNormal" style="line-height: 150%"><span lang="EN-US" style="line-height: 150%; font-family: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: arial"><span style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp; </span>z = SIZEOF(Data, b);//---- 128<o:p></o:p></span></p> <p class="MsoNormal" style="line-height: 150%"><span lang="EN-US" style="line-height: 150%; font-family: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: arial"><span style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp; </span>z = SIZEOF(Data, c);//---- 128<o:p></o:p></span></p> <p class="MsoNormal" style="line-height: 150%"><span lang="EN-US" style="line-height: 150%; font-family: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: arial"><span style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp; </span>z = SIZEOF(Data, b[0]);//---- 4<o:p></o:p></span></p> <p class="MsoNormal" style="line-height: 150%"><span lang="EN-US" style="line-height: 150%; font-family: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: arial"><span style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp; </span>z = SIZEOF(Data, c[0]);//---- 1<o:p></o:p></span></p> <p class="MsoNormal" style="line-height: 150%"><span lang="EN-US" style="line-height: 150%; font-family: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: arial"><span style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp; </span>return 1;<o:p></o:p></span></p> <p class="MsoNormal" style="line-height: 150%"><span lang="EN-US" style="line-height: 150%; font-family: 宋体; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: arial">}<o:p></o:p></span></p><img src ="http://www.cppblog.com/woaidongmao/aggbug/68096.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/woaidongmao/" target="_blank">肥仔</a> 2008-11-28 18:56 <a href="http://www.cppblog.com/woaidongmao/archive/2008/11/28/68096.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C中如何调用C++函数</title><link>http://www.cppblog.com/woaidongmao/archive/2008/11/26/67919.html</link><dc:creator>肥仔</dc:creator><author>肥仔</author><pubDate>Wed, 26 Nov 2008 09:14:00 GMT</pubDate><guid>http://www.cppblog.com/woaidongmao/archive/2008/11/26/67919.html</guid><wfw:comment>http://www.cppblog.com/woaidongmao/comments/67919.html</wfw:comment><comments>http://www.cppblog.com/woaidongmao/archive/2008/11/26/67919.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/woaidongmao/comments/commentRss/67919.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/woaidongmao/services/trackbacks/67919.html</trackback:ping><description><![CDATA[<p class="MsoNormal" style="background: white; word-break: break-all; text-indent: 24pt; line-height: 160%; text-align: left; mso-char-indent-count: 2.0; mso-pagination: widow-orphan" align="left"><span style="font-size: 12pt; color: black; line-height: 160%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">前阵子被问及一个在<span lang="EN-US">C</span>中如何调用<span lang="EN-US">C++</span>函数的问题，当时简单回答是将函数用<span lang="EN-US">extern "C"</span>声明，当被问及如何将类内成员函数声明时，一时语塞，后来网上查了下，网上有一翻译<span lang="EN-US">C++</span>之父的文章可以作为解答，遂拿来<span lang="EN-US">Mark</span>一下。<span lang="EN-US"><?xml:namespace prefix = o /><o:p></o:p></span></span></p> <p class="MsoNormal" style="background: white; word-break: break-all; text-indent: 24pt; line-height: 160%; text-align: left; mso-char-indent-count: 2.0; mso-pagination: widow-orphan" align="left"><span lang="EN-US" style="font-size: 12pt; color: black; line-height: 160%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">&nbsp;<o:p></o:p></span></p> <p class="MsoNormal" style="background: white; word-break: break-all; text-indent: 24pt; line-height: 160%; text-align: left; mso-char-indent-count: 2.0; mso-pagination: widow-orphan" align="left"><span style="font-size: 12pt; color: black; line-height: 160%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">将<span lang="EN-US"> C++ </span>函数声明为<span lang="EN-US">``extern "C"''</span>（在你的<span lang="EN-US"> C++ </span>代码里做这个声明），然后调用它（在你的<span lang="EN-US"> C </span>或者<span lang="EN-US"> C++ </span>代码里调用）。例如：<span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal" style="background: #d9d9d9; word-break: break-all; text-indent: 24pt; line-height: 160%; text-align: left; mso-char-indent-count: 2.0; mso-pagination: widow-orphan" align="left"><span lang="EN-US" style="font-size: 12pt; color: black; line-height: 160%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">// C++ code:<o:p></o:p></span></p> <p class="MsoNormal" style="background: #d9d9d9; word-break: break-all; text-indent: 24pt; line-height: 160%; text-align: left; mso-char-indent-count: 2.0; mso-pagination: widow-orphan" align="left"><span lang="EN-US" style="font-size: 12pt; color: black; line-height: 160%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">extern "C" void f(int); <o:p></o:p></span></p> <p class="MsoNormal" style="background: #d9d9d9; word-break: break-all; text-indent: 24pt; line-height: 160%; text-align: left; mso-char-indent-count: 2.0; mso-pagination: widow-orphan" align="left"><span lang="EN-US" style="font-size: 12pt; color: black; line-height: 160%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">void f(int i)<o:p></o:p></span></p> <p class="MsoNormal" style="background: #d9d9d9; word-break: break-all; text-indent: 24pt; line-height: 160%; text-align: left; mso-char-indent-count: 2.0; mso-pagination: widow-orphan" align="left"><span lang="EN-US" style="font-size: 12pt; color: black; line-height: 160%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">{<o:p></o:p></span></p> <p class="MsoNormal" style="background: #d9d9d9; word-break: break-all; text-indent: 24pt; line-height: 160%; text-align: left; mso-char-indent-count: 2.0; mso-pagination: widow-orphan" align="left"><span lang="EN-US" style="font-size: 12pt; color: black; line-height: 160%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp; </span>// ...<o:p></o:p></span></p> <p class="MsoNormal" style="background: #d9d9d9; word-break: break-all; text-indent: 24pt; line-height: 160%; text-align: left; mso-char-indent-count: 2.0; mso-pagination: widow-orphan" align="left"><span lang="EN-US" style="font-size: 12pt; color: black; line-height: 160%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">} <o:p></o:p></span></p> <p class="MsoNormal" style="background: #d9d9d9; word-break: break-all; text-indent: 24pt; line-height: 160%; text-align: left; mso-char-indent-count: 2.0; mso-pagination: widow-orphan" align="left"><span lang="EN-US" style="font-size: 12pt; color: black; line-height: 160%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">&nbsp;<o:p></o:p></span></p> <p class="MsoNormal" style="background: white; word-break: break-all; text-indent: 24pt; line-height: 160%; text-align: left; mso-char-indent-count: 2.0; mso-pagination: widow-orphan" align="left"><span style="font-size: 12pt; color: black; line-height: 160%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">然后，你可以这样使用<span lang="EN-US"> f()</span>： <span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal" style="background: #d9d9d9; word-break: break-all; text-indent: 24pt; line-height: 160%; text-align: left; mso-char-indent-count: 2.0; mso-pagination: widow-orphan" align="left"><span lang="DE" style="font-size: 12pt; color: black; line-height: 160%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt; mso-ansi-language: de">/* C code: */</span><span lang="EN-US" style="font-size: 12pt; color: black; line-height: 160%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><o:p></o:p></span></p> <p class="MsoNormal" style="background: #d9d9d9; word-break: break-all; text-indent: 24pt; line-height: 160%; text-align: left; mso-char-indent-count: 2.0; mso-pagination: widow-orphan" align="left"><span lang="EN-US" style="font-size: 12pt; color: black; line-height: 160%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">void f(int); <o:p></o:p></span></p> <p class="MsoNormal" style="background: #d9d9d9; word-break: break-all; text-indent: 24pt; line-height: 160%; text-align: left; mso-char-indent-count: 2.0; mso-pagination: widow-orphan" align="left"><span lang="EN-US" style="font-size: 12pt; color: black; line-height: 160%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">void cc(int i)<o:p></o:p></span></p> <p class="MsoNormal" style="background: #d9d9d9; word-break: break-all; text-indent: 24pt; line-height: 160%; text-align: left; mso-char-indent-count: 2.0; mso-pagination: widow-orphan" align="left"><span lang="EN-US" style="font-size: 12pt; color: black; line-height: 160%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">{<o:p></o:p></span></p> <p class="MsoNormal" style="background: #d9d9d9; word-break: break-all; text-indent: 24pt; line-height: 160%; text-align: left; mso-char-indent-count: 2.0; mso-pagination: widow-orphan" align="left"><span lang="EN-US" style="font-size: 12pt; color: black; line-height: 160%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span>f(i);<o:p></o:p></span></p> <p class="MsoNormal" style="background: #d9d9d9; word-break: break-all; text-indent: 30pt; line-height: 160%; text-align: left; mso-char-indent-count: 2.5; mso-pagination: widow-orphan" align="left"><span lang="EN-US" style="font-size: 12pt; color: black; line-height: 160%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp; </span>/* ... */<o:p></o:p></span></p> <p class="MsoNormal" style="background: #d9d9d9; word-break: break-all; line-height: 160%; text-align: left; mso-pagination: widow-orphan" align="left"><span lang="EN-US" style="font-size: 12pt; color: black; line-height: 160%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span>}<o:p></o:p></span></p> <p class="MsoNormal" style="background: white; word-break: break-all; text-indent: 24pt; line-height: 160%; text-align: left; mso-char-indent-count: 2.0; mso-pagination: widow-orphan" align="left"><span lang="EN-US" style="font-size: 12pt; color: black; line-height: 160%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">&nbsp;<o:p></o:p></span></p> <p class="MsoNormal" style="background: white; word-break: break-all; text-indent: 24pt; line-height: 160%; text-align: left; mso-char-indent-count: 2.0; mso-pagination: widow-orphan" align="left"><span style="font-size: 12pt; color: black; line-height: 160%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">当然，这招只适用于非成员函数。如果你想要在<span lang="EN-US"> C </span>里调用成员函数（包括虚函数），则需要提供一个简单的包装（<span lang="EN-US">wrapper</span>）。例如：<span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal" style="background: #d9d9d9; word-break: break-all; text-indent: 24pt; line-height: 160%; text-align: left; mso-char-indent-count: 2.0; mso-pagination: widow-orphan" align="left"><span lang="EN-US" style="font-size: 12pt; color: black; line-height: 160%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">// C++ code:<o:p></o:p></span></p> <p class="MsoNormal" style="background: #d9d9d9; word-break: break-all; text-indent: 24pt; line-height: 160%; text-align: left; mso-char-indent-count: 2.0; mso-pagination: widow-orphan" align="left"><span lang="EN-US" style="font-size: 12pt; color: black; line-height: 160%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">class C<o:p></o:p></span></p> <p class="MsoNormal" style="background: #d9d9d9; word-break: break-all; text-indent: 24pt; line-height: 160%; text-align: left; mso-char-indent-count: 2.0; mso-pagination: widow-orphan" align="left"><span lang="EN-US" style="font-size: 12pt; color: black; line-height: 160%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">{<o:p></o:p></span></p> <p class="MsoNormal" style="background: #d9d9d9; word-break: break-all; text-indent: 24pt; line-height: 160%; text-align: left; mso-char-indent-count: 2.0; mso-pagination: widow-orphan" align="left"><span lang="EN-US" style="font-size: 12pt; color: black; line-height: 160%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><span style="mso-tab-count: 1">&nbsp;&nbsp; </span>// ...<o:p></o:p></span></p> <p class="MsoNormal" style="background: #d9d9d9; word-break: break-all; text-indent: 24pt; line-height: 160%; text-align: left; mso-char-indent-count: 2.0; mso-pagination: widow-orphan" align="left"><span lang="EN-US" style="font-size: 12pt; color: black; line-height: 160%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><span style="mso-tab-count: 1">&nbsp;&nbsp; </span>virtual double f(int);<o:p></o:p></span></p> <p class="MsoNormal" style="background: #d9d9d9; word-break: break-all; text-indent: 24pt; line-height: 160%; text-align: left; mso-char-indent-count: 2.0; mso-pagination: widow-orphan" align="left"><span lang="EN-US" style="font-size: 12pt; color: black; line-height: 160%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">}; <o:p></o:p></span></p> <p class="MsoNormal" style="background: #d9d9d9; word-break: break-all; text-indent: 24pt; line-height: 160%; text-align: left; mso-char-indent-count: 2.0; mso-pagination: widow-orphan" align="left"><span lang="EN-US" style="font-size: 12pt; color: black; line-height: 160%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">&nbsp;<o:p></o:p></span></p> <p class="MsoNormal" style="background: #d9d9d9; word-break: break-all; text-indent: 24pt; line-height: 160%; text-align: left; mso-char-indent-count: 2.0; mso-pagination: widow-orphan" align="left"><span lang="EN-US" style="font-size: 12pt; color: black; line-height: 160%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">extern "C" double call_C_f(C* p, int i) // wrapper function<o:p></o:p></span></p> <p class="MsoNormal" style="background: #d9d9d9; word-break: break-all; text-indent: 24pt; line-height: 160%; text-align: left; mso-char-indent-count: 2.0; mso-pagination: widow-orphan" align="left"><span lang="EN-US" style="font-size: 12pt; color: black; line-height: 160%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">{<o:p></o:p></span></p> <p class="MsoNormal" style="background: #d9d9d9; word-break: break-all; text-indent: 24pt; line-height: 160%; text-align: left; mso-char-indent-count: 2.0; mso-pagination: widow-orphan" align="left"><span lang="EN-US" style="font-size: 12pt; color: black; line-height: 160%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><span style="mso-tab-count: 1">&nbsp;&nbsp; </span>return p-&gt;f(i);<o:p></o:p></span></p> <p class="MsoNormal" style="background: #d9d9d9; word-break: break-all; text-indent: 24pt; line-height: 160%; text-align: left; mso-char-indent-count: 2.0; mso-pagination: widow-orphan" align="left"><span lang="EN-US" style="font-size: 12pt; color: black; line-height: 160%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">}<o:p></o:p></span></p> <p class="MsoNormal" style="background: white; word-break: break-all; text-indent: 24pt; line-height: 160%; text-align: left; mso-char-indent-count: 2.0; mso-pagination: widow-orphan" align="left"><span lang="EN-US" style="font-size: 12pt; color: black; line-height: 160%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">&nbsp;<o:p></o:p></span></p> <p class="MsoNormal" style="background: white; word-break: break-all; text-indent: 24pt; line-height: 160%; text-align: left; mso-char-indent-count: 2.0; mso-pagination: widow-orphan" align="left"><span style="font-size: 12pt; color: black; line-height: 160%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">然后，你就可以这样调用<span lang="EN-US"> C::f()</span>： <span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal" style="background: #d9d9d9; word-break: break-all; text-indent: 24pt; line-height: 160%; text-align: left; mso-char-indent-count: 2.0; mso-pagination: widow-orphan" align="left"><span lang="EN-US" style="font-size: 12pt; color: black; line-height: 160%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">/* C code: */<o:p></o:p></span></p> <p class="MsoNormal" style="background: #d9d9d9; word-break: break-all; text-indent: 24pt; line-height: 160%; text-align: left; mso-char-indent-count: 2.0; mso-pagination: widow-orphan" align="left"><span lang="EN-US" style="font-size: 12pt; color: black; line-height: 160%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">double call_C_f(struct C* p, int i); <o:p></o:p></span></p> <p class="MsoNormal" style="background: #d9d9d9; word-break: break-all; text-indent: 24pt; line-height: 160%; text-align: left; mso-char-indent-count: 2.0; mso-pagination: widow-orphan" align="left"><span lang="EN-US" style="font-size: 12pt; color: black; line-height: 160%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">&nbsp;<o:p></o:p></span></p> <p class="MsoNormal" style="background: #d9d9d9; word-break: break-all; text-indent: 24pt; line-height: 160%; text-align: left; mso-char-indent-count: 2.0; mso-pagination: widow-orphan" align="left"><span lang="EN-US" style="font-size: 12pt; color: black; line-height: 160%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">void ccc(struct C* p, int i)<o:p></o:p></span></p> <p class="MsoNormal" style="background: #d9d9d9; word-break: break-all; text-indent: 24pt; line-height: 160%; text-align: left; mso-char-indent-count: 2.0; mso-pagination: widow-orphan" align="left"><span lang="EN-US" style="font-size: 12pt; color: black; line-height: 160%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">{<o:p></o:p></span></p> <p class="MsoNormal" style="background: #d9d9d9; word-break: break-all; text-indent: 24pt; line-height: 160%; text-align: left; mso-char-indent-count: 2.0; mso-pagination: widow-orphan" align="left"><span lang="EN-US" style="font-size: 12pt; color: black; line-height: 160%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><span style="mso-tab-count: 1">&nbsp;&nbsp; </span>double d = call_C_f(p,i);<o:p></o:p></span></p> <p class="MsoNormal" style="background: #d9d9d9; word-break: break-all; text-indent: 24pt; line-height: 160%; text-align: left; mso-char-indent-count: 2.0; mso-pagination: widow-orphan" align="left"><span lang="EN-US" style="font-size: 12pt; color: black; line-height: 160%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><span style="mso-tab-count: 1">&nbsp;&nbsp; </span>/* ... */<o:p></o:p></span></p> <p class="MsoNormal" style="background: #d9d9d9; word-break: break-all; text-indent: 24pt; line-height: 160%; text-align: left; mso-char-indent-count: 2.0; mso-pagination: widow-orphan" align="left"><span lang="EN-US" style="font-size: 12pt; color: black; line-height: 160%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">} <o:p></o:p></span></p> <p class="MsoNormal" style="background: white; word-break: break-all; text-indent: 24pt; line-height: 160%; text-align: left; mso-char-indent-count: 2.0; mso-pagination: widow-orphan" align="left"><span lang="EN-US" style="font-size: 12pt; color: black; line-height: 160%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">&nbsp;<o:p></o:p></span></p> <p class="MsoNormal" style="background: white; word-break: break-all; text-indent: 24pt; line-height: 160%; text-align: left; mso-char-indent-count: 2.0; mso-pagination: widow-orphan" align="left"><span style="font-size: 12pt; color: black; line-height: 160%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">如果你想在<span lang="EN-US"> C </span>里调用重载函数，则必须提供不同名字的包装，这样才能被<span lang="EN-US"> C </span>代码调用。例如</span><span style="font-size: 12pt; color: black; line-height: 160%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt; mso-ansi-language: de">：</span><span lang="EN-US" style="font-size: 12pt; color: black; line-height: 160%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><o:p></o:p></span></p> <p class="MsoNormal" style="background: #d9d9d9; word-break: break-all; text-indent: 24pt; line-height: 160%; text-align: left; mso-char-indent-count: 2.0; mso-pagination: widow-orphan" align="left"><span lang="DE" style="font-size: 12pt; color: black; line-height: 160%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt; mso-ansi-language: de">// C++ code:</span><span lang="EN-US" style="font-size: 12pt; color: black; line-height: 160%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><o:p></o:p></span></p> <p class="MsoNormal" style="background: #d9d9d9; word-break: break-all; text-indent: 24pt; line-height: 160%; text-align: left; mso-char-indent-count: 2.0; mso-pagination: widow-orphan" align="left"><span lang="DE" style="font-size: 12pt; color: black; line-height: 160%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt; mso-ansi-language: de">void f(int);</span><span lang="EN-US" style="font-size: 12pt; color: black; line-height: 160%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><o:p></o:p></span></p> <p class="MsoNormal" style="background: #d9d9d9; word-break: break-all; text-indent: 24pt; line-height: 160%; text-align: left; mso-char-indent-count: 2.0; mso-pagination: widow-orphan" align="left"><span lang="EN-US" style="font-size: 12pt; color: black; line-height: 160%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">void f(double); <o:p></o:p></span></p> <p class="MsoNormal" style="background: #d9d9d9; word-break: break-all; text-indent: 24pt; line-height: 160%; text-align: left; mso-char-indent-count: 2.0; mso-pagination: widow-orphan" align="left"><span lang="EN-US" style="font-size: 12pt; color: black; line-height: 160%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">&nbsp;<o:p></o:p></span></p> <p class="MsoNormal" style="background: #d9d9d9; word-break: break-all; text-indent: 24pt; line-height: 160%; text-align: left; mso-char-indent-count: 2.0; mso-pagination: widow-orphan" align="left"><span lang="EN-US" style="font-size: 12pt; color: black; line-height: 160%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">extern "C" void f_i(int i) { f(i); }<o:p></o:p></span></p> <p class="MsoNormal" style="background: #d9d9d9; word-break: break-all; text-indent: 24pt; line-height: 160%; text-align: left; mso-char-indent-count: 2.0; mso-pagination: widow-orphan" align="left"><span lang="EN-US" style="font-size: 12pt; color: black; line-height: 160%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">extern "C" void f_d(double d) { f(d); } <o:p></o:p></span></p> <p class="MsoNormal" style="background: white; word-break: break-all; text-indent: 24pt; line-height: 160%; text-align: left; mso-char-indent-count: 2.0; mso-pagination: widow-orphan" align="left"><span lang="EN-US" style="font-size: 12pt; color: black; line-height: 160%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">&nbsp;<o:p></o:p></span></p> <p class="MsoNormal" style="background: white; word-break: break-all; text-indent: 24pt; line-height: 160%; text-align: left; mso-char-indent-count: 2.0; mso-pagination: widow-orphan" align="left"><span style="font-size: 12pt; color: black; line-height: 160%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">然后，你可以这样使用每个重载的<span lang="EN-US"> f()</span>： <span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal" style="background: #d9d9d9; word-break: break-all; text-indent: 24pt; line-height: 160%; text-align: left; mso-char-indent-count: 2.0; mso-pagination: widow-orphan" align="left"><span lang="EN-US" style="font-size: 12pt; color: black; line-height: 160%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">/* C code: */<o:p></o:p></span></p> <p class="MsoNormal" style="background: #d9d9d9; word-break: break-all; text-indent: 24pt; line-height: 160%; text-align: left; mso-char-indent-count: 2.0; mso-pagination: widow-orphan" align="left"><span lang="EN-US" style="font-size: 12pt; color: black; line-height: 160%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">void f_i(int);<o:p></o:p></span></p> <p class="MsoNormal" style="background: #d9d9d9; word-break: break-all; text-indent: 24pt; line-height: 160%; text-align: left; mso-char-indent-count: 2.0; mso-pagination: widow-orphan" align="left"><span lang="EN-US" style="font-size: 12pt; color: black; line-height: 160%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">void f_d(double); <o:p></o:p></span></p> <p class="MsoNormal" style="background: #d9d9d9; word-break: break-all; text-indent: 24pt; line-height: 160%; text-align: left; mso-char-indent-count: 2.0; mso-pagination: widow-orphan" align="left"><span lang="EN-US" style="font-size: 12pt; color: black; line-height: 160%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">&nbsp;<o:p></o:p></span></p> <p class="MsoNormal" style="background: #d9d9d9; word-break: break-all; text-indent: 24pt; line-height: 160%; text-align: left; mso-char-indent-count: 2.0; mso-pagination: widow-orphan" align="left"><span lang="EN-US" style="font-size: 12pt; color: black; line-height: 160%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">void cccc(int i,double d)<o:p></o:p></span></p> <p class="MsoNormal" style="background: #d9d9d9; word-break: break-all; text-indent: 24pt; line-height: 160%; text-align: left; mso-char-indent-count: 2.0; mso-pagination: widow-orphan" align="left"><span lang="EN-US" style="font-size: 12pt; color: black; line-height: 160%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">{<o:p></o:p></span></p> <p class="MsoNormal" style="background: #d9d9d9; word-break: break-all; text-indent: 24pt; line-height: 160%; text-align: left; mso-char-indent-count: 2.0; mso-pagination: widow-orphan" align="left"><span lang="EN-US" style="font-size: 12pt; color: black; line-height: 160%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><span style="mso-tab-count: 1">&nbsp;&nbsp; </span>f_i(i);<o:p></o:p></span></p> <p class="MsoNormal" style="background: #d9d9d9; word-break: break-all; text-indent: 24pt; line-height: 160%; text-align: left; mso-char-indent-count: 2.0; mso-pagination: widow-orphan" align="left"><span lang="EN-US" style="font-size: 12pt; color: black; line-height: 160%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><span style="mso-tab-count: 1">&nbsp;&nbsp; </span>f_d(d);<o:p></o:p></span></p> <p class="MsoNormal" style="background: #d9d9d9; word-break: break-all; text-indent: 24pt; line-height: 160%; text-align: left; mso-char-indent-count: 2.0; mso-pagination: widow-orphan" align="left"><span lang="EN-US" style="font-size: 12pt; color: black; line-height: 160%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><span style="mso-tab-count: 1">&nbsp;&nbsp; </span>/* ... */<o:p></o:p></span></p> <p class="MsoNormal" style="background: #d9d9d9; word-break: break-all; text-indent: 24pt; line-height: 160%; text-align: left; mso-char-indent-count: 2.0; mso-pagination: widow-orphan" align="left"><span lang="EN-US" style="font-size: 12pt; color: black; line-height: 160%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">} <o:p></o:p></span></p> <p class="MsoNormal" style="background: white; word-break: break-all; text-indent: 24pt; line-height: 160%; text-align: left; mso-char-indent-count: 2.0; mso-pagination: widow-orphan" align="left"><span style="font-size: 12pt; color: black; line-height: 160%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">注意，这些技巧也适用于在<span lang="EN-US"> C </span>里调用<span lang="EN-US"> C++ </span>类库，即使你不能（或者不想）修改<span lang="EN-US"> C++ </span>头文件。<span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal"><span lang="EN-US" style="font-size: 12pt; color: black; font-family: 宋体; mso-bidi-font-family: arial"><o:p>&nbsp;</o:p></span></p> <p class="MsoNormal"><font color="#ff0000">extern "C" 之后,就不能重载函数了,关键还是函数名修饰的问题.</font></p><img src ="http://www.cppblog.com/woaidongmao/aggbug/67919.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/woaidongmao/" target="_blank">肥仔</a> 2008-11-26 17:14 <a href="http://www.cppblog.com/woaidongmao/archive/2008/11/26/67919.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C++中使用union的几点思考</title><link>http://www.cppblog.com/woaidongmao/archive/2008/11/21/67530.html</link><dc:creator>肥仔</dc:creator><author>肥仔</author><pubDate>Fri, 21 Nov 2008 14:07:00 GMT</pubDate><guid>http://www.cppblog.com/woaidongmao/archive/2008/11/21/67530.html</guid><wfw:comment>http://www.cppblog.com/woaidongmao/comments/67530.html</wfw:comment><comments>http://www.cppblog.com/woaidongmao/archive/2008/11/21/67530.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/woaidongmao/comments/commentRss/67530.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/woaidongmao/services/trackbacks/67530.html</trackback:ping><description><![CDATA[<p></p> <p class="MsoNormal" style="word-break: break-all; line-height: 150%"><span style="font-size: 12pt; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial">大卫注<b><span lang="EN-US" style="color: #663300">:</span></b><span lang="EN-US"><br></span>这段时间整理旧资料<b><span lang="EN-US" style="color: #663300">,</span></b>看到一些文章<b><span lang="EN-US" style="color: #663300">,</span></b>虽然讲的都是些小问题<b><span lang="EN-US" style="color: #663300">,</span></b>不大可能用到<b><span lang="EN-US" style="color: #663300">,</span></b>但也算是一个知识点<b><span lang="EN-US" style="color: #663300">,</span></b>特整理出来与大家共享<b><span lang="EN-US" style="color: #663300">.</span></b>与此相关的那篇文章的作者的有些理解是错误的<b><span lang="EN-US" style="color: #663300">,</span></b>我写此文<b><span lang="EN-US" style="color: #663300">,</span></b>也是纠正为了作者的一些错误认识<b><span lang="EN-US" style="color: #663300">.</span></b>当然<b><span lang="EN-US" style="color: #663300">,</span></b>如果我的理解有任何错误<b><span lang="EN-US" style="color: #663300">,</span></b>也恳请大家批评指正<b><span lang="EN-US" style="color: #663300">.</span></b><span lang="EN-US"><br><br>C<b><span style="color: #663300">++</span></b></span>虽说被<span lang="EN-US">B<b><span style="color: #663300">.</span></b>S<b><span style="color: #663300">.</span></b></span>称作一门新语言<b><span lang="EN-US" style="color: #663300">,</span></b>但它毕竟与<span lang="EN-US">C</span>有着千丝万缕的联系<b><span lang="EN-US" style="color: #663300">,</span></b>虽然<span lang="EN-US">B<b><span style="color: #663300">.</span></b>S<b><span style="color: #663300">.</span></b></span>一再坚持<b><span lang="EN-US" style="color: #663300">,</span></b>但我还是愿意把<span lang="EN-US">C<b><span style="color: #663300">++</span></b></span>看作是<span lang="EN-US">C<b><span style="color: #663300"> ++.</span></b><br></span>我们应该按照<span lang="EN-US">C</span>中的<span lang="EN-US">convention</span>去使用<span lang="EN-US" style="color: #990000">union</span><b><span lang="EN-US" style="color: #663300">,</span></b>这是我这篇文章要给出的观点<b><span lang="EN-US" style="color: #663300">.</span></b>虽然<span lang="EN-US">C<b><span style="color: #663300">++</span></b></span>使得我们可以扩展一些新的东西进去<b><span lang="EN-US" style="color: #663300">,</span></b>但是<b><span lang="EN-US" style="color: #663300">,</span></b>我建议你不要那样去做<b><span lang="EN-US" style="color: #663300">,</span></b>看完这篇文章之后<b><span lang="EN-US" style="color: #663300">,</span></b>我想你大概也是这么想的<b><span lang="EN-US" style="color: #663300">.</span></b><span lang="EN-US"><br><br>C</span>由于没有类的概念<b><span lang="EN-US" style="color: #663300">,</span></b>所有类型其实都可以看作是基本类型的组合<b><span lang="EN-US" style="color: #663300">,</span></b>因此在<span lang="EN-US" style="color: #990000">union</span>中包含<span lang="EN-US" style="color: #990000">struct</span>也就是一件很自然的事情了<b><span lang="EN-US" style="color: #663300">,</span></b>到了<span lang="EN-US">C<b><span style="color: #663300">++</span></b></span>之后<b><span lang="EN-US" style="color: #663300">,</span></b>既然普遍认为<span lang="EN-US">C<b><span style="color: #663300">++</span></b></span>中的<span lang="EN-US" style="color: #990000">struct</span>与<span lang="EN-US" style="color: #990000">class</span>基本等价<b><span lang="EN-US" style="color: #663300">,</span></b>那么<span lang="EN-US" style="color: #990000">union</span>中是否可以有类成员呢<b><span lang="EN-US" style="color: #663300">?</span></b>先来看看如下的代码<b><span lang="EN-US" style="color: #663300">:</span></b><span lang="EN-US" style="color: #990000"><br><br>struct</span><span lang="EN-US"> TestUnion<b><span style="color: #663300"><br>{</span></b><br>&nbsp;&nbsp;&nbsp; TestUnion<b><span style="color: #663300">() {}<br>};</span></b><span style="color: #990000"><br><br>typedef union</span><b><span style="color: #663300"><br>{</span></b><br>&nbsp;&nbsp;&nbsp; TestUnion obj<b><span style="color: #663300">;<br>}</span></b> UT<b><span style="color: #663300">;</span></b><span style="color: #ff6633"><br><br>int</span><span style="color: #990000"> main</span><b><span style="color: #663300"> (</span></b><span style="color: #ff6633">void</span><b><span style="color: #663300">)<br>{</span></b><span style="color: red"><br>&nbsp;&nbsp;&nbsp; return</span><span style="color: #999900"> 0</span><b><span style="color: #663300">;<br>}</span></b><br><br></span>编译该程序<b><span lang="EN-US" style="color: #663300">,</span></b>我们将被告知<b><span lang="EN-US" style="color: #663300">:</span></b><span lang="EN-US"><br>error C2620<b><span style="color: #663300">:</span></b><span style="color: #990000"> union</span><span style="color: #009900"> '__unnamed'</span><b><span style="color: #663300"> :</span></b> member<span style="color: #009900"> 'obj'</span> has user<b><span style="color: #663300">-</span></b>defined constructor<span style="color: #990000"> or</span> non<b><span style="color: #663300">-</span></b>trivial<span style="color: red"> default</span> constructor<br></span>而如果去掉那个什么也没干的构造函数<b><span lang="EN-US" style="color: #663300">,</span></b>则一切<span lang="EN-US">OK<b><span style="color: #663300">.</span></b><br><br></span>为什么编译器不允许我们的<span lang="EN-US" style="color: #990000">union</span>成员有构造函数呢<b><span lang="EN-US" style="color: #663300">?</span></b>我无法找到关于这个问题的比较权威的解释<b><span lang="EN-US" style="color: #663300">,</span></b>对这个问题<b><span lang="EN-US" style="color: #663300">,</span></b>我的解释是<b><span lang="EN-US" style="color: #663300">:</span></b><span lang="EN-US"><br></span>如果<span lang="EN-US">C<b><span style="color: #663300">++</span></b></span>标准允许我们的<span lang="EN-US" style="color: #990000">union</span>有构造函数<b><span lang="EN-US" style="color: #663300">,</span></b>那么<b><span lang="EN-US" style="color: #663300">,</span></b>在进行空间分配的时候要不要执行这个构造函数呢<b><span lang="EN-US" style="color: #663300">?</span></b>如果答案是<span lang="EN-US">yes<b><span style="color: #663300">,</span></b></span>那么如果<span lang="EN-US">TestUnion</span>的构造函数中包含了一些内存分配操作<b><span lang="EN-US" style="color: #663300">,</span></b>或者其它对整个<span lang="EN-US">application</span>状态的修改<b><span lang="EN-US" style="color: #663300">,</span></b>那么<b><span lang="EN-US" style="color: #663300">,</span></b>如果我今后要用到<span lang="EN-US">obj</span>的话<b><span lang="EN-US" style="color: #663300">,</span></b>事情可能还比较合理<b><span lang="EN-US" style="color: #663300">,</span></b>但是如果我根本就不使用<span lang="EN-US">obj</span>这个成员呢<b><span lang="EN-US" style="color: #663300">?</span></b>由于<span lang="EN-US">obj</span>的引入造成的对系统状态的修改显然是不合理的<b><span lang="EN-US" style="color: #663300">;</span></b>反之<b><span lang="EN-US" style="color: #663300">,</span></b>如果答案是<span lang="EN-US">no<b><span style="color: #663300">,</span></b></span>那么一旦我们今后选中了<span lang="EN-US">obj</span>来进行操作<b><span lang="EN-US" style="color: #663300">,</span></b>则所有信息都没有初始化<b><span lang="EN-US" style="color: #663300">(</span></b>如果是普通的<span lang="EN-US" style="color: #990000">struct</span><b><span lang="EN-US" style="color: #663300">,</span></b>没什么问题<b><span lang="EN-US" style="color: #663300">,</span></b>但是<b><span lang="EN-US" style="color: #663300">,</span></b>如果有虚函数呢<b><span lang="EN-US" style="color: #663300">?).</span></b>更进一步<b><span lang="EN-US" style="color: #663300">,</span></b>假设现在我们的<span lang="EN-US" style="color: #990000">union</span>不是只有一个<span lang="EN-US">TestUnion obj<b><span style="color: #663300">,</span></b></span>还有一个<span lang="EN-US">TestUnion2 obj2<b><span style="color: #663300">,</span></b></span>二者均有构造函数<b><span lang="EN-US" style="color: #663300">,</span></b>并且都在构造函数中执行了一些内存分配的工作<b><span lang="EN-US" style="color: #663300">(</span></b>甚至干了很多其它事情<b><span lang="EN-US" style="color: #663300">),</span></b>那么<b><span lang="EN-US" style="color: #663300">,</span></b>如果先构造<span lang="EN-US">obj<b><span style="color: #663300">,</span></b></span>后构造<span lang="EN-US">obj2<b><span style="color: #663300">,</span></b></span>则执行的结果几乎可以肯定会造成内存的泄漏<b><span lang="EN-US" style="color: #663300">.</span></b><span lang="EN-US"><br></span>鉴于以上诸多麻烦<b><span lang="EN-US" style="color: #663300">(</span></b>可能还有更多麻烦<b><span lang="EN-US" style="color: #663300">),</span></b>在构造<span lang="EN-US" style="color: #990000">union</span>时<b><span lang="EN-US" style="color: #663300">,</span></b>编译器只负责分配空间<b><span lang="EN-US" style="color: #663300">,</span></b>而不负责去执行附加的初始化工作<b><span lang="EN-US" style="color: #663300">,</span></b>为了简化工作<b><span lang="EN-US" style="color: #663300">,</span></b>只要我们提供了构造函数<b><span lang="EN-US" style="color: #663300">,</span></b>就会收到上面的<span lang="EN-US">error<b><span style="color: #663300">.</span></b><br></span>同理<b><span lang="EN-US" style="color: #663300">,</span></b>除了不能加构造函数<b><span lang="EN-US" style="color: #663300">,</span></b>析构函数<b><span lang="EN-US" style="color: #663300">/</span></b>拷贝构造函数<b><span lang="EN-US" style="color: #663300">/</span></b>赋值运算符也是不可以加<b><span lang="EN-US" style="color: #663300">.</span></b><span lang="EN-US"><br><br></span>此外<b><span lang="EN-US" style="color: #663300">,</span></b>如果我们的类中包含了任何<span lang="EN-US" style="color: #990000">virtual</span>函数<b><span lang="EN-US" style="color: #663300">,</span></b>编译时<b><span lang="EN-US" style="color: #663300">,</span></b>我们将收到如下的错误信息<b><span lang="EN-US" style="color: #663300">:</span></b><span lang="EN-US"><br>error C2621<b><span style="color: #663300">:</span></b><span style="color: #990000"> union</span><span style="color: #009900"> '__unnamed'</span><b><span style="color: #663300"> :</span></b> member<span style="color: #009900"> 'obj'</span> has copy constructor<br><br></span>所以<b><span lang="EN-US" style="color: #663300">,</span></b>打消在<span lang="EN-US" style="color: #990000">union</span>中包含有构造函数<b><span lang="EN-US" style="color: #663300">/</span></b>析构函数<b><span lang="EN-US" style="color: #663300">/</span></b>拷贝构造函数<b><span lang="EN-US" style="color: #663300">/</span></b>赋值运算符<b><span lang="EN-US" style="color: #663300">/</span></b>虚函数的类成员变量的念头<b><span lang="EN-US" style="color: #663300">,</span></b>老老实实用你的<span lang="EN-US">C</span>风格<span lang="EN-US" style="color: #990000">struct</span>吧<b><span lang="EN-US" style="color: #663300">!</span></b><span lang="EN-US"><br></span>不过<b><span lang="EN-US" style="color: #663300">,</span></b>定义普通的成员函数是<span lang="EN-US">OK</span>的<b><span lang="EN-US" style="color: #663300">,</span></b>因为这不会使得<span lang="EN-US" style="color: #990000">class</span>与<span lang="EN-US">C</span>风格的<span lang="EN-US" style="color: #990000">struct</span>有任何本质区别<b><span lang="EN-US" style="color: #663300">,</span></b>你完全可以将这样的<span lang="EN-US" style="color: #990000">class</span>理解为一个<span lang="EN-US">C</span>风格的<span lang="EN-US" style="color: #990000">struct</span><b><span lang="EN-US" style="color: #663300"> +</span></b><span lang="EN-US"> n</span>个全局函数<b><span lang="EN-US" style="color: #663300">.</span></b><span lang="EN-US"><br><br></span>现在<b><span lang="EN-US" style="color: #663300">,</span></b>再看看在类中包含内部<span lang="EN-US" style="color: #990000">union</span>时会有什么不同<b><span lang="EN-US" style="color: #663300">.</span></b>看看下面的程序<b><span lang="EN-US" style="color: #663300">,</span></b>并请注意阅读程序提示<b><span lang="EN-US" style="color: #663300">:</span></b><span lang="EN-US" style="color: #990000"><br><br>class</span><span lang="EN-US"> TestUnion<b><span style="color: #663300"><br>{</span></b><span style="color: #990000"><br>&nbsp;&nbsp;&nbsp; union</span> DataUnion<b><span style="color: #663300"><br>&nbsp;&nbsp;&nbsp; {</span></b><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DataUnion<b><span style="color: #663300">(</span></b><span style="color: #990000">const</span><span style="color: #ff6633"> char</span><b><span style="color: #663300">*);</span></b><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DataUnion<b><span style="color: #663300">(</span></b><span style="color: #ff6633">long</span><b><span style="color: #663300">);</span></b><span style="color: #990000"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; const</span><span style="color: #ff6633"> char</span><b><span style="color: #663300">*</span></b> ch_<b><span style="color: #663300">;</span></b><span style="color: #ff6633"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; long</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; l_<b><span style="color: #663300">;<br>&nbsp;&nbsp;&nbsp; }</span></b> data_<b><span style="color: #663300">;</span></b><span style="color: #990000"><br><br>public</span><b><span style="color: #663300">:</span></b><br>&nbsp;&nbsp;&nbsp; TestUnion<b><span style="color: #663300">(</span></b><span style="color: #990000">const</span><span style="color: #ff6633"> char</span><b><span style="color: #663300">*</span></b> ch<b><span style="color: #663300">);</span></b><br>&nbsp;&nbsp;&nbsp; TestUnion<b><span style="color: #663300">(</span></b><span style="color: #ff6633">long</span> l<b><span style="color: #663300">);<br>};</span></b><br><br>TestUnion<b><span style="color: #663300">::</span></b>TestUnion<b><span style="color: #663300">(</span></b><span style="color: #990000">const</span><span style="color: #ff6633"> char</span><b><span style="color: #663300">*</span></b> ch<b><span style="color: #663300">) :</span></b> data_<b><span style="color: #663300">(</span></b>ch<b><span style="color: #663300">)</span></b><i><span style="color: #999999"> // if you want to use initialzing list to initiate a nested-union member, the union must not be anonymous and must have a constructor.<br></span></i><b><span style="color: #663300">{<br>}</span></b><br><br>TestUnion<b><span style="color: #663300">::</span></b>TestUnion<b><span style="color: #663300">(</span></b><span style="color: #ff6633">long</span> l<b><span style="color: #663300">) :</span></b> data_<b><span style="color: #663300">(</span></b>l<b><span style="color: #663300">)<br>{<br>}</span></b><br><br>TestUnion<b><span style="color: #663300">::</span></b>DataUnion<b><span style="color: #663300">::</span></b>DataUnion<b><span style="color: #663300">(</span></b><span style="color: #990000">const</span><span style="color: #ff6633"> char</span><b><span style="color: #663300">*</span></b> ch<b><span style="color: #663300">) :</span></b> ch_<b><span style="color: #663300">(</span></b>ch<b><span style="color: #663300">)<br>{<br>}</span></b><br><br>TestUnion<b><span style="color: #663300">::</span></b>DataUnion<b><span style="color: #663300">::</span></b>DataUnion<b><span style="color: #663300">(</span></b><span style="color: #ff6633">long</span> l<b><span style="color: #663300">) :</span></b> l_<b><span style="color: #663300">(</span></b>l<b><span style="color: #663300">)<br>{<br>}</span></b><span style="color: #ff6633"><br><br>int</span><span style="color: #990000"> main</span><b><span style="color: #663300"> (</span></b><span style="color: #ff6633">void</span><b><span style="color: #663300">)<br>{</span></b><span style="color: red"><br>&nbsp;&nbsp;&nbsp; return</span><span style="color: #999900"> 0</span><b><span style="color: #663300">;<br>}</span></b><br><br></span>正如上面程序所示<b><span lang="EN-US" style="color: #663300">,</span></b><span lang="EN-US">C<b><span style="color: #663300">++</span></b></span>中的<span lang="EN-US" style="color: #990000">union</span>也可以包含构造函数<b><span lang="EN-US" style="color: #663300">,</span></b>但是<b><span lang="EN-US" style="color: #663300">,</span></b>这虽然被语言所支持<b><span lang="EN-US" style="color: #663300">,</span></b>但实在是一种不佳的编程习惯<b><span lang="EN-US" style="color: #663300">,</span></b>因此<b><span lang="EN-US" style="color: #663300">,</span></b>我不打算对上面的程序进行过多的说明<b><span lang="EN-US" style="color: #663300">.</span></b>我更推荐如下的编程风格<b><span lang="EN-US" style="color: #663300">:</span></b><span lang="EN-US" style="color: #990000"><br><br>class</span><span lang="EN-US"> TestUnion<b><span style="color: #663300"><br>{</span></b><span style="color: #990000"><br>&nbsp;&nbsp;&nbsp; union</span> DataUnion<b><span style="color: #663300"><br>&nbsp;&nbsp;&nbsp; {</span></b><span style="color: #990000"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; const</span><span style="color: #ff6633"> char</span><b><span style="color: #663300">*</span></b> ch_<b><span style="color: #663300">;</span></b><span style="color: #ff6633"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; long</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; l_<b><span style="color: #663300">;<br>&nbsp;&nbsp;&nbsp; }</span></b> data_<b><span style="color: #663300">;</span></b><span style="color: #990000"><br>&nbsp;&nbsp;&nbsp; <br>public</span><b><span style="color: #663300">:</span></b><br>&nbsp;&nbsp;&nbsp; TestUnion<b><span style="color: #663300">(</span></b><span style="color: #990000">const</span><span style="color: #ff6633"> char</span><b><span style="color: #663300">*</span></b> ch<b><span style="color: #663300">);</span></b><br>&nbsp;&nbsp;&nbsp; TestUnion<b><span style="color: #663300">(</span></b><span style="color: #ff6633">long</span> l<b><span style="color: #663300">);<br>};</span></b><br><br>TestUnion<b><span style="color: #663300">::</span></b>TestUnion<b><span style="color: #663300">(</span></b><span style="color: #990000">const</span><span style="color: #ff6633"> char</span><b><span style="color: #663300">*</span></b> ch<b><span style="color: #663300">)<br>{</span></b><br>&nbsp;&nbsp;&nbsp; data_<b><span style="color: #663300">.</span></b>ch_<b><span style="color: #663300"> =</span></b> ch<b><span style="color: #663300">;<br>}</span></b><br><br>TestUnion<b><span style="color: #663300">::</span></b>TestUnion<b><span style="color: #663300">(</span></b><span style="color: #ff6633">long</span> l<b><span style="color: #663300">)<br>{</span></b><br>&nbsp;&nbsp;&nbsp; data_<b><span style="color: #663300">.</span></b>l_<b><span style="color: #663300"> =</span></b> l<b><span style="color: #663300">;<br>}</span></b><span style="color: #ff6633"><br><br>int</span><span style="color: #990000"> main</span><b><span style="color: #663300"> (</span></b><span style="color: #ff6633">void</span><b><span style="color: #663300">)<br>{</span></b><span style="color: red"><br>&nbsp;&nbsp;&nbsp; return</span><span style="color: #999900"> 0</span><b><span style="color: #663300">;<br>}</span></b><br><br></span>它完全是<span lang="EN-US">C</span>风格的<b><span lang="EN-US" style="color: #663300">.</span></b><span lang="EN-US"><br><br></span>所以<b><span lang="EN-US" style="color: #663300">,</span></b>接受这个结论吧<b><span lang="EN-US" style="color: #663300">:</span></b><span lang="EN-US"><br></span>请按照<span lang="EN-US">C</span>中的<span lang="EN-US">convention</span>去使用<span lang="EN-US" style="color: #990000">union</span><b><span lang="EN-US" style="color: #663300">,</span></b>尽量不要尝试使用任何<span lang="EN-US">C<b><span style="color: #663300">++</span></b></span>附加特性<b><span lang="EN-US" style="color: #663300">.</span></b><span lang="EN-US"> <?xml:namespace prefix = o /><o:p></o:p></span></span></p> <div style="border-right: medium none; padding-right: 0cm; border-top: #dddddd 1pt solid; padding-left: 0cm; padding-bottom: 0cm; border-left: medium none; padding-top: 0cm; border-bottom: medium none; mso-element: para-border-div; mso-border-top-alt: solid #dddddd .75pt"> <p class="postfoot2" style="word-break: break-all; line-height: 150%"><span lang="EN-US" style="font-size: 12pt; line-height: 150%; mso-bidi-font-family: arial">posted on 2004-11-12 09:08 </span><span style="font-size: 12pt; line-height: 150%; mso-bidi-font-family: arial">大卫的思维空间 阅读<span lang="EN-US">(8069) <a href="http://blog.vckbase.com/billdavid/archive/2006/07/07/1482.html#Post#Post"><span lang="EN-US"><span lang="EN-US">评论(16)</span></span></a>&nbsp; <a href="http://blog.vckbase.com/billdavid/admin/EditPosts.aspx?postid=1482"><span lang="EN-US"><span lang="EN-US">编辑</span></span></a>&nbsp;<a href="http://blog.vckbase.com/billdavid/AddToFavorite.aspx?id=1482"><span lang="EN-US"><span lang="EN-US">收藏</span></span></a> <o:p></o:p></span></span></p></div> <div style="border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; padding-bottom: 0cm; margin-left: 7.5pt; border-left: medium none; margin-right: 7.5pt; padding-top: 0cm; border-bottom: #aaaaaa 1pt solid; mso-element: para-border-div; mso-border-bottom-alt: solid #aaaaaa .75pt"> <p class="MsoNormal" style="border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; padding-bottom: 0cm; border-left: medium none; word-break: break-all; padding-top: 0cm; border-bottom: medium none; mso-border-bottom-alt: solid #aaaaaa .75pt; mso-outline-level: 4; mso-padding-alt: 0cm 0cm 0cm 0cm"><a name="评论"><b><span style="font-size: 12pt; color: #223355; font-family: 宋体; mso-bidi-font-family: arial"><link href="http://blog.vckbase.com/billdavid/Services/Pingback.aspx" rel="pingback">评论<span lang="EN-US"><o:p></o:p></span></span></b></a></p></div><span style="mso-bookmark: 评论"></span> <p class="MsoNormal" style="margin-bottom: 3pt; word-break: break-all; line-height: 150%; mso-outline-level: 3"><b><span lang="EN-US" style="font-size: 12pt; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial"><a title="permalink: &quot;比较权威的解释&quot;, B.S权威不？可惜你不看他的书。" href="http://blog.vckbase.com/billdavid/archive/2004/11/12/1482.html#1486">#</a>&nbsp;<a name="1486"></a>"</span></b><b><span style="font-size: 12pt; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial">比较权威的解释<span lang="EN-US">", B.S</span>权威不？可惜你不看他的书。 <span lang="EN-US"><a id="Comments1_CommentList__ctl0_EditLink" href=""></a><o:p></o:p></span></span></b></p> <p class="MsoNormal" style="word-break: break-all; line-height: 150%"><span style="font-size: 12pt; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial">以下摘自《<span lang="EN-US"> the c++ programming language 3rd </span>》，对为什么<span lang="EN-US">union</span>不支持构造函数和析构函数，推荐怎么使用<span lang="EN-US">unions</span>都有说明。<span lang="EN-US"> <?xml:namespace prefix = st1 /><st1:chsdate w:st="on" isrocdate="False" islunardate="False" day="30" month="12" year="1899"><br><br>10.4.12</st1:chsdate> Unions [class.union] <br>A named union is defined as a struct, where every member has the same address (see §C.8.2). A <br>union can have member functions but not static members. <br>In general, a compiler cannot know what member of a union is used; that is, the type of the <br>object stored in a union is unknown. Consequently, a union may not have members with constructors <br>or destructors. It wouldn’t be possible to protect that object against corruption or to guarantee <br>that the right destructor is called when the union goes out of scope. <br>Unions are best used in lowlevel <br>code, or as part of the implementation of classes that keep <br>track of what is stored in the union (see §10.6[20]). <br><br></span>其实正如在<span lang="EN-US">vckbase/c++</span>论坛上我对你说的，想想<span lang="EN-US">union</span>的用途就可以了。<span lang="EN-US">union</span>的出现是为了解决一组不定类型数据的空间紧张问题，它是为省空间用的，不是为了封装数据和方法。所以我觉得大卫兄太过于刨根究底了，而忽略了<span lang="EN-US">C++</span>的实用性<span lang="EN-US">(</span>实用性是<span lang="EN-US">C/C++</span>的首要设计思想<span lang="EN-US">) <o:p></o:p></span></span></p> <p class="MsoNormal" style="word-break: break-all; line-height: 150%"><span lang="EN-US" style="font-size: 12pt; color: #aaaaaa; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial">2004-11-12 10:18 | <a id="Comments1_CommentList__ctl0_NameLink" href="http://blog.vckbase.com/smileonce" target="_blank"><span lang="EN-US"><span lang="EN-US">一笑</span></span></a> <o:p></o:p></span></p> <p class="MsoNormal" style="margin-bottom: 3pt; word-break: break-all; line-height: 150%; mso-outline-level: 3"><b><span lang="EN-US" style="font-size: 12pt; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial"><a title="permalink: re: (大卫的阅读笔记)C++中使用union的几点思考" href="http://blog.vckbase.com/billdavid/archive/2004/11/12/1482.html#1500">#</a>&nbsp;<a name="1500"></a>re: (</span></b><b><span style="font-size: 12pt; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial">大卫的阅读笔记<span lang="EN-US">)C++</span>中使用<span lang="EN-US">union</span>的几点思考 <span lang="EN-US"><a id="Comments1_CommentList__ctl1_EditLink" href=""></a><o:p></o:p></span></span></b></p> <p class="MsoNormal" style="word-break: break-all; line-height: 150%"><span style="font-size: 12pt; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial">谢谢笑兄给出的<span lang="EN-US">CPL</span>中的相关论述<span lang="EN-US">.</span>我现在主要关注的内容并非<span lang="EN-US">C++(</span>虽然<span lang="EN-US">C++</span>是我最喜欢的语言<span lang="EN-US">),</span>我在<span lang="EN-US">blog</span>上发布这些文章也只是希望谈一下自己对于某些语言特性或新技术的认识<span lang="EN-US">,</span>以期对后来者有些许帮助<span lang="EN-US">,</span>同时<span lang="EN-US">,</span>也希望在与大家的交流中提高自己<span lang="EN-US">. <br>^_^,</span>也许我真的有点刨根究底<span lang="EN-US">,</span>不过笑兄的关于<span lang="EN-US">"union</span>是为省空间用的<span lang="EN-US">"</span>的观点我不认同<span lang="EN-US">,</span>虽然<span lang="EN-US">,</span>我也看到过类似的说法<span lang="EN-US">,</span>但是<span lang="EN-US">,union</span>怎么可能节省空间呢<span lang="EN-US">?</span>如<span lang="EN-US">: <br>union uT <br>{ <br>int i; <br>char c; <br>}; <br></span>当他被作为<span lang="EN-US">char</span>使用时<span lang="EN-US">,</span>明明浪费了空间<span lang="EN-US">. <br></span>只是从另一角度出发<span lang="EN-US">:</span>把它当成一种特殊的<span lang="EN-US">struct,</span>与<span lang="EN-US">struct</span>相比时才可以勉强说是节省了空间<span lang="EN-US">. <br></span>我认为<span lang="EN-US">union</span>的引入<span lang="EN-US">,</span>更多地是提供了一种解决多种型别共同使用同一空间<span lang="EN-US">(</span>这与节省空间是两回事<span lang="EN-US">)</span>的机制<span lang="EN-US">,</span>借助这种机制<span lang="EN-US">,</span>我们可以提供更丰富的语言表现力<span lang="EN-US">. <br></span>为此<span lang="EN-US">,</span>我决定再写一篇文章<span lang="EN-US">,</span>谈一些比较有意思<span lang="EN-US">/</span>有意义的<span lang="EN-US">union</span>的使用<span lang="EN-US">,</span>请关注<span lang="EN-US"> &amp; </span>批评指正<span lang="EN-US">. <o:p></o:p></span></span></p> <p class="MsoNormal" style="word-break: break-all; line-height: 150%"><span lang="EN-US" style="font-size: 12pt; color: #aaaaaa; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial">2004-11-13 05:11 | <a id="Comments1_CommentList__ctl1_NameLink" href="http://blog.vckbase.com/billdavid/" target="_blank">Bill David</a> <o:p></o:p></span></p> <p class="MsoNormal" style="margin-bottom: 3pt; word-break: break-all; line-height: 150%; mso-outline-level: 3"><b><span lang="EN-US" style="font-size: 12pt; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial"><a title="permalink: 对union的进一步认识与一些深层应用" href="http://blog.vckbase.com/billdavid/archive/2004/11/12/1482.html#1783">#</a>&nbsp;</span></b><a name="1783"></a><b><span style="font-size: 12pt; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial">对<span lang="EN-US">union</span>的进一步认识与一些深层应用<span lang="EN-US">[TrackBack] <a id="Comments1_CommentList__ctl2_EditLink" href=""></a><o:p></o:p></span></span></b></p> <p class="MsoNormal" style="word-break: break-all; line-height: 150%"><span lang="EN-US" style="font-size: 12pt; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial">Ping Back</span><span style="font-size: 12pt; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial">来自：<span lang="EN-US">blog.csdn.net<br>Bill David</span>引用了该文章<span lang="EN-US">,</span>地址<span lang="EN-US">:<a href="http://blog.csdn.net/billdavid/archive/2004/11/26/195006.aspx">http://blog.csdn.net/billdavid/archive/2004/11/26/195006.aspx</a> <o:p></o:p></span></span></p> <p class="MsoNormal" style="word-break: break-all; line-height: 150%"><span lang="EN-US" style="font-size: 12pt; color: #aaaaaa; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial">2004-11-26 18:58 | <a id="Comments1_CommentList__ctl2_NameLink" href="http://blog.csdn.net/billdavid/archive/2004/11/26/195006.aspx" target="_blank">Bill David</a> <o:p></o:p></span></p> <p class="MsoNormal" style="margin-bottom: 3pt; word-break: break-all; line-height: 150%; mso-outline-level: 3"><b><span lang="EN-US" style="font-size: 12pt; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial"><a title="permalink: re: (大卫的阅读笔记)C++中使用union的几点思考" href="http://blog.vckbase.com/billdavid/archive/2004/11/12/1482.html#4825">#</a>&nbsp;<a name="4825"></a>re: (</span></b><b><span style="font-size: 12pt; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial">大卫的阅读笔记<span lang="EN-US">)C++</span>中使用<span lang="EN-US">union</span>的几点思考 <span lang="EN-US"><a id="Comments1_CommentList__ctl3_EditLink" href=""></a><o:p></o:p></span></span></b></p> <p class="MsoNormal" style="word-break: break-all; line-height: 150%"><span style="font-size: 12pt; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial">呵呵，仁者见仁，智者见智。<span lang="EN-US"> <br></span>但是<span lang="EN-US">union</span>的确应该是节省空间使用的。当时的初衷是这样的。但是后来就不一定了。<span lang="EN-US">3ks </span>二位。 <span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal" style="word-break: break-all; line-height: 150%"><span lang="EN-US" style="font-size: 12pt; color: #aaaaaa; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial">2005-04-19 17:38 | <a id="Comments1_CommentList__ctl3_NameLink" href="http://blog.vckbase.com/flyingleaf" target="_blank"><span lang="EN-US"><span lang="EN-US">漫天飞舞</span></span></a> <o:p></o:p></span></p> <p class="MsoNormal" style="margin-bottom: 3pt; word-break: break-all; line-height: 150%; mso-outline-level: 3"><b><span lang="EN-US" style="font-size: 12pt; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial"><a title="permalink: 今日经论坛匿名大侠指点，union还有一个重要的特性" href="http://blog.vckbase.com/billdavid/archive/2004/11/12/1482.html#4826">#</a>&nbsp;</span></b><a name="4826"></a><b><span style="font-size: 12pt; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial">今日经论坛匿名大侠指点，<span lang="EN-US">union</span>还有一个重要的特性 <span lang="EN-US"><a id="Comments1_CommentList__ctl4_EditLink" href=""></a><o:p></o:p></span></span></b></p> <p class="MsoNormal" style="word-break: break-all; line-height: 150%"><span lang="EN-US" style="font-size: 12pt; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial">union</span><span style="font-size: 12pt; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial">不支持继承。<span lang="EN-US"> <br><br></span>特记录于此。 <span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal" style="word-break: break-all; line-height: 150%"><span lang="EN-US" style="font-size: 12pt; color: #aaaaaa; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial">2005-04-19 17:59 | <a id="Comments1_CommentList__ctl4_NameLink" href="http://blog.vckbase.com/billdavid" target="_blank">Bill David</a> <o:p></o:p></span></p> <p class="MsoNormal" style="margin-bottom: 3pt; word-break: break-all; line-height: 150%; mso-outline-level: 3"><b><span lang="EN-US" style="font-size: 12pt; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial"><a title="permalink: re: union不支持继承。" href="http://blog.vckbase.com/billdavid/archive/2004/11/12/1482.html#20104">#</a>&nbsp;<a name="20104"></a>re: union</span></b><b><span style="font-size: 12pt; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial">不支持继承。 <span lang="EN-US"><a id="Comments1_CommentList__ctl5_EditLink" href=""></a><o:p></o:p></span></span></b></p> <p class="MsoNormal" style="word-break: break-all; line-height: 150%"><span style="font-size: 12pt; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial">我突然觉得如果<span lang="EN-US">union</span>设计为可继承的也未尝不可。<span lang="EN-US"> <br>union base <br>{ <br>&nbsp;&nbsp;&nbsp; int mem1; <br>&nbsp;&nbsp;&nbsp; char mem2; <br>}; <br></span>这个假设被原实现者设计好了，突然，某天我想在<span lang="EN-US">base</span>的基础上添加一些特性，于是我写<span lang="EN-US"> <br>union derive : base <br>{ <br>&nbsp;&nbsp;&nbsp; short mem 3; <br>}; <br></span>或许可能实际意义不大吧！但，如果这么说，我<span lang="EN-US">reinterpret_cast</span>成员<span lang="EN-US">mem1</span>呢？<span lang="EN-US">union</span>的实际意义又有多大呢？<span lang="EN-US"> <br><br></span>不知道你怎么看？ <span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal" style="word-break: break-all; line-height: 150%"><span lang="EN-US" style="font-size: 12pt; color: #aaaaaa; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial">2006-05-16 13:35 | <a id="Comments1_CommentList__ctl5_NameLink" href="http://blog.vckbase.com/zhangJW_cn" target="_blank"><span lang="EN-US"><span lang="EN-US">清风雨</span></span></a> <o:p></o:p></span></p> <p class="MsoNormal" style="margin-bottom: 3pt; word-break: break-all; line-height: 150%; mso-outline-level: 3"><b><span lang="EN-US" style="font-size: 12pt; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial"><a title="permalink: re: union的几点思考" href="http://blog.vckbase.com/billdavid/archive/2004/11/12/1482.html#20105">#</a>&nbsp;<a name="20105"></a>re: union</span></b><b><span style="font-size: 12pt; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial">的几点思考 <span lang="EN-US"><a id="Comments1_CommentList__ctl6_EditLink" href=""></a><o:p></o:p></span></span></b></p> <p class="MsoNormal" style="word-break: break-all; line-height: 150%"><span style="font-size: 12pt; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial">又看了你的另一篇<span lang="EN-US">union</span>的，可能我比较懒惰的缘故，我只得到一个结论：<span lang="EN-US"> union</span>仅仅只是为了方便。 <span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal" style="word-break: break-all; line-height: 150%"><span lang="EN-US" style="font-size: 12pt; color: #aaaaaa; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial">2006-05-16 13:49 | <a id="Comments1_CommentList__ctl6_NameLink" href="http://blog.vckbase.com/zhangJW_cn" target="_blank"><span lang="EN-US"><span lang="EN-US">清风雨</span></span></a> <o:p></o:p></span></p> <p class="MsoNormal" style="margin-bottom: 3pt; word-break: break-all; line-height: 150%; mso-outline-level: 3"><b><span lang="EN-US" style="font-size: 12pt; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial"><a title="permalink: re: (大卫的阅读笔记)C++中使用union的几点思考" href="http://blog.vckbase.com/billdavid/archive/2004/11/12/1482.html#20174">#</a>&nbsp;<a name="20174"></a>re: (</span></b><b><span style="font-size: 12pt; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial">大卫的阅读笔记<span lang="EN-US">)C++</span>中使用<span lang="EN-US">union</span>的几点思考 <span lang="EN-US"><a id="Comments1_CommentList__ctl7_EditLink" href=""></a><o:p></o:p></span></span></b></p> <p class="MsoNormal" style="word-break: break-all; line-height: 150%"><span style="font-size: 12pt; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial">这都是些什么<span lang="EN-US">? <o:p></o:p></span></span></p> <p class="MsoNormal" style="word-break: break-all; line-height: 150%"><span lang="EN-US" style="font-size: 12pt; color: #aaaaaa; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial">2006-05-18 21:35 | </span><span style="font-size: 12pt; color: #aaaaaa; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial">一二三 <span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal" style="margin-bottom: 3pt; word-break: break-all; line-height: 150%; mso-outline-level: 3"><b><span lang="EN-US" style="font-size: 12pt; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial"><a title="permalink: re: (大卫的阅读笔记)C++中使用union的几点思考" href="http://blog.vckbase.com/billdavid/archive/2004/11/12/1482.html#20175">#</a>&nbsp;<a name="20175"></a>re: (</span></b><b><span style="font-size: 12pt; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial">大卫的阅读笔记<span lang="EN-US">)C++</span>中使用<span lang="EN-US">union</span>的几点思考 <span lang="EN-US"><a id="Comments1_CommentList__ctl8_EditLink" href=""></a><o:p></o:p></span></span></b></p> <p class="MsoNormal" style="word-break: break-all; line-height: 150%"><span style="font-size: 12pt; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial">看不懂 <span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal" style="word-break: break-all; line-height: 150%"><span lang="EN-US" style="font-size: 12pt; color: #aaaaaa; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial">2006-05-18 21:36 | </span><span style="font-size: 12pt; color: #aaaaaa; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial">一二三 <span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal" style="margin-bottom: 3pt; word-break: break-all; line-height: 150%; mso-outline-level: 3"><b><span lang="EN-US" style="font-size: 12pt; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial"><a title="permalink: re: (大卫的阅读笔记)C++中使用union的几点思考" href="http://blog.vckbase.com/billdavid/archive/2004/11/12/1482.html#21125">#</a>&nbsp;<a name="21125"></a>re: (</span></b><b><span style="font-size: 12pt; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial">大卫的阅读笔记<span lang="EN-US">)C++</span>中使用<span lang="EN-US">union</span>的几点思考 <span lang="EN-US"><a id="Comments1_CommentList__ctl9_EditLink" href=""></a><o:p></o:p></span></span></b></p> <p class="MsoNormal" style="word-break: break-all; line-height: 150%"><span lang="EN-US" style="font-size: 12pt; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial">union <br>{ <br>&nbsp;&nbsp;&nbsp; struct <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; { <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; string name; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }info; <br>&nbsp;&nbsp;&nbsp; int&nbsp; age; <br>}information; <br><br></span><span style="font-size: 12pt; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial">上面的语句可能出错<span lang="EN-US">,has copy constructor.&nbsp;&nbsp; </span>难道只有把<span lang="EN-US">string --&gt;char *</span>吗<span lang="EN-US">?? <o:p></o:p></span></span></p> <p class="MsoNormal" style="word-break: break-all; line-height: 150%"><span lang="EN-US" style="font-size: 12pt; color: #aaaaaa; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial">2006-07-07 15:38 | Tmin <o:p></o:p></span></p> <p class="MsoNormal" style="margin-bottom: 3pt; word-break: break-all; line-height: 150%; mso-outline-level: 3"><b><span lang="EN-US" style="font-size: 12pt; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial"><a title="permalink: re: (大卫的阅读笔记)C++中使用union的几点思考" href="http://blog.vckbase.com/billdavid/archive/2004/11/12/1482.html#22788">#</a>&nbsp;<a name="22788"></a>re: (</span></b><b><span style="font-size: 12pt; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial">大卫的阅读笔记<span lang="EN-US">)C++</span>中使用<span lang="EN-US">union</span>的几点思考 <span lang="EN-US"><a id="Comments1_CommentList__ctl10_EditLink" href=""></a><o:p></o:p></span></span></b></p> <p class="MsoNormal" style="word-break: break-all; line-height: 150%"><span style="font-size: 12pt; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial">看了文章和回帖，我非常同意一笑兄的看法。我觉得作者没有完全理解<span lang="EN-US">“</span>节省空间<span lang="EN-US">”</span>的指的是如何节省，例如我们获取一些信息时，需要把信息数据填充到一个结构中，但是我们需要的信息的数据的类型会根据情况不同而不同，如果我们为了通用的话，可能就需要为所有可能出现的类型都预留相应的空间来存储，但是每次只能使用其中一个有效。其他预留无效。这显然是浪费空间的。所以<span lang="EN-US">union</span>使得不同类型数据存放在内存的同一个位置，当然这个空间的大小是能容纳所有类型的数据的。因为<span lang="EN-US">unicon</span>的数据类型是运行时决定的，事先并不知道，所以为<span lang="EN-US">union</span>做一个构造函数是没有意义的。 <span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal" style="word-break: break-all; line-height: 150%"><span lang="EN-US" style="font-size: 12pt; color: #aaaaaa; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial">2006-10-17 11:48 | hoodlum <o:p></o:p></span></p> <p class="MsoNormal" style="margin-bottom: 3pt; word-break: break-all; line-height: 150%; mso-outline-level: 3"><b><span lang="EN-US" style="font-size: 12pt; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial"><a title="permalink: re: (大卫的阅读笔记)C++中使用union的几点思考" href="http://blog.vckbase.com/billdavid/archive/2004/11/12/1482.html#22789">#</a>&nbsp;<a name="22789"></a>re: (</span></b><b><span style="font-size: 12pt; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial">大卫的阅读笔记<span lang="EN-US">)C++</span>中使用<span lang="EN-US">union</span>的几点思考 <span lang="EN-US"><a id="Comments1_CommentList__ctl11_EditLink" href=""></a><o:p></o:p></span></span></b></p> <p class="MsoNormal" style="word-break: break-all; line-height: 150%"><span style="font-size: 12pt; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial">刚才回的仓促，可能有论述不是很恰当。但是看了作者的另一篇文章里面引用的英文，论述的也和我本来的想法是一致的。也就是说，可以使用<span lang="EN-US">union.memberData</span>来访问成员，但是应该注意的是，使用时只有其中一个成员才是有意义的。<span lang="EN-US">union</span>占用的空间大小是所有成员数据大小的最小公倍数。（因此，转为托管代码中就可以使用一个能够容纳<span lang="EN-US">union</span>大小的数据类型来代替，或者用通用的字节数组）<span lang="EN-US"> <br><br></span>例如下面的例子（来自<span lang="EN-US">Windows API</span>）： <span lang="EN-US"><br>union <br> {&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp; DWORD dwOemId;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp; struct { <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; WORD wProcessorArchitecture;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; WORD wReserved;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }; <br>&nbsp; }; <br><br></span>它通常占用<span lang="EN-US">4</span>个字节，因此可以使用托管代码中的<span lang="EN-US">Int32</span>来代替。<span lang="EN-US"> <br></span>其中<span lang="EN-US">dwOemId</span>是为了向前兼容某些系统版本，当前已经弃用。这样，一个程序对<span lang="EN-US">API</span>的调用可以在不同版本的系统中运转良好，处理各自自己需要的数据。 <span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal"><span lang="EN-US" style="font-size: 12pt; font-family: 宋体; mso-bidi-font-family: arial"><o:p>&nbsp;</o:p></span></p><img src ="http://www.cppblog.com/woaidongmao/aggbug/67530.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/woaidongmao/" target="_blank">肥仔</a> 2008-11-21 22:07 <a href="http://www.cppblog.com/woaidongmao/archive/2008/11/21/67530.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>聪明反被聪明误，一个bug</title><link>http://www.cppblog.com/woaidongmao/archive/2008/11/20/67386.html</link><dc:creator>肥仔</dc:creator><author>肥仔</author><pubDate>Thu, 20 Nov 2008 08:32:00 GMT</pubDate><guid>http://www.cppblog.com/woaidongmao/archive/2008/11/20/67386.html</guid><wfw:comment>http://www.cppblog.com/woaidongmao/comments/67386.html</wfw:comment><comments>http://www.cppblog.com/woaidongmao/archive/2008/11/20/67386.html#Feedback</comments><slash:comments>7</slash:comments><wfw:commentRss>http://www.cppblog.com/woaidongmao/comments/commentRss/67386.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/woaidongmao/services/trackbacks/67386.html</trackback:ping><description><![CDATA[<p>愿望是：在执行一个迭代过程中，所有foo()的调用都返回TRUE，bSuccess才为TRUE. 写成了如下的代码，真是机关算尽太聪明，反算了卿卿性命。</p> <p>&nbsp;</p> <p>BOOL foo(int index);</p> <p>&nbsp;</p> <p>BOOL bSuccess = TRUE;</p> <p>for(int i = 0; i &lt; value; ++i)</p> <p>{</p> <p>&nbsp;&nbsp;&nbsp; bSuccess = (bSuccess &amp;&amp; foo(i));</p> <p>}</p><img src ="http://www.cppblog.com/woaidongmao/aggbug/67386.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/woaidongmao/" target="_blank">肥仔</a> 2008-11-20 16:32 <a href="http://www.cppblog.com/woaidongmao/archive/2008/11/20/67386.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>比int更低的无符号数相操作后的结果的类型原来是int</title><link>http://www.cppblog.com/woaidongmao/archive/2008/11/19/67335.html</link><dc:creator>肥仔</dc:creator><author>肥仔</author><pubDate>Wed, 19 Nov 2008 14:33:00 GMT</pubDate><guid>http://www.cppblog.com/woaidongmao/archive/2008/11/19/67335.html</guid><wfw:comment>http://www.cppblog.com/woaidongmao/comments/67335.html</wfw:comment><comments>http://www.cppblog.com/woaidongmao/archive/2008/11/19/67335.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/woaidongmao/comments/commentRss/67335.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/woaidongmao/services/trackbacks/67335.html</trackback:ping><description><![CDATA[<p>比如 unsigned short a=2, b=1;<br>a-b 的类型是 int，不是 unsigned short<br>a+b 也是 int <p>&nbsp;</p> <p>&nbsp;</p> <p>unsigned char a=2, b=1; <br>也会得到同样的结果。 <br>答案是：无论a+b还是a-b，不超过int范围的数值运算表达式最终都会以一个int类型作为结果类型 <img src ="http://www.cppblog.com/woaidongmao/aggbug/67335.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/woaidongmao/" target="_blank">肥仔</a> 2008-11-19 22:33 <a href="http://www.cppblog.com/woaidongmao/archive/2008/11/19/67335.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>const在C和C++中的一个区别</title><link>http://www.cppblog.com/woaidongmao/archive/2008/11/19/67334.html</link><dc:creator>肥仔</dc:creator><author>肥仔</author><pubDate>Wed, 19 Nov 2008 14:32:00 GMT</pubDate><guid>http://www.cppblog.com/woaidongmao/archive/2008/11/19/67334.html</guid><wfw:comment>http://www.cppblog.com/woaidongmao/comments/67334.html</wfw:comment><comments>http://www.cppblog.com/woaidongmao/archive/2008/11/19/67334.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/woaidongmao/comments/commentRss/67334.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/woaidongmao/services/trackbacks/67334.html</trackback:ping><description><![CDATA[<p></p> <p>一个文件中<br>&nbsp;&nbsp;&nbsp; const int a = 1;<br>另一个文件中<br>&nbsp;&nbsp;&nbsp; extern const int a;<br>&nbsp;&nbsp;&nbsp; cout &lt;&lt; a &lt;&lt; endl;<br>类似的代码在C中OK，但在C++中没能Link通过。 <p>改为<br>一个文件中<br>extern "C" {<br>&nbsp;&nbsp;&nbsp; const int a = 1;<br>}<br>另一个文件中<br>extern "C" {<br>&nbsp;&nbsp;&nbsp; extern const int a;<br>&nbsp;&nbsp;&nbsp; cout &lt;&lt; a &lt;&lt; endl;<br>}<br>在C++中也没能Link通过。 <p><a href="http://www.vckbase.com/bbs/userinfo.asp?id=全局变量">[全局变量]</a>给我的解答是： <p>C and C++ const Differences<br>When you declare a variable as const in a C source code file, you do so as:  <p>const int i = 2; <p>You can then use this variable in another module as follows: <p>extern const int i; <p>But to get the same behavior in C++, you must declare your const variable as: <p>extern const int i = 2; <p>If you wish to declare an extern variable in a C++ source code file for use in a C source code file, use: <p>extern "C" const int x=10; <p>to prevent name mangling by the C++ compiler. <p>于是我改为<br>一个文件中<br>&nbsp;&nbsp;&nbsp; extern "C" const int a = 1;<br>另一个文件中<br>&nbsp;&nbsp;&nbsp; extern "C" const int a;<br>&nbsp;&nbsp;&nbsp; cout &lt;&lt; a &lt;&lt; endl;<br>在C++中OK <p>改为<br>一个文件中<br>extern "C" {<br>&nbsp;&nbsp;&nbsp; extern "C" const int a = 1;<br>}<br>另一个文件中<br>extern "C" {<br>&nbsp;&nbsp;&nbsp; extern "C" const int a;<br>}<br>在C++中也OK <p>看来 extern "C" 和 extern "C" {} 还是有区别的^_^<br>----------------------------------------<br>const在C和C++中的其他区别不说了，比如const在C++偏向于“常量”，而在C中偏向于“只读”<br>简单的说，在C++中，a 是一个编译期常量，所以不进obj文件，用extern无效。<br>在这种情况下，C++都是建议把他放到头文件中去的。 <p>posted on 2006-10-31 17:23 周星星 阅读(4342) <a href="http://blog.vckbase.com/#Post">评论(2)</a> <a href="http://blog.vckbase.com/bruceteen/admin/EditPosts.aspx?postid=22934">编辑</a> <a href="http://blog.vckbase.com/bruceteen/AddToFavorite.aspx?id=22934">收藏</a> <p><a name="评论"> <h5>评论</h5> <p><a href="http://blog.vckbase.com/bruceteen/archive/2006/10/31/22934.html#23060">#</a> <a name="23060"></a>re: const在C和C++中的一个区别 2006-11-10 21:41 <a>路人甲</a> <p>记得c++编程思想第1卷中好象讲过这个问题,c++中const是内连接的. <br><a href="http://blog.vckbase.com/"></a> <p><a href="http://blog.vckbase.com/bruceteen/archive/2006/10/31/22934.html#30862">#</a> <a name="30862"></a>re: const在C和C++中的一个区别<a name="Post"></a> 2007-11-23 16:34 <a>空见</a> <p>//***a.cpp*** <br>#include &lt;iostream&gt; <br>extern const int i; <br>void main () <br>{ <br>&nbsp; std::cout &lt;&lt; i; <br>} <br>//***b.cpp*** <br>extern const int i = 10; <br>执行结果： <br>10 <br>不关extern "C"的事情，正如路人甲所说，是const的内连接特性造成的  <p></a></p><img src ="http://www.cppblog.com/woaidongmao/aggbug/67334.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/woaidongmao/" target="_blank">肥仔</a> 2008-11-19 22:32 <a href="http://www.cppblog.com/woaidongmao/archive/2008/11/19/67334.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>对union的进一步认识与一些深层应用</title><link>http://www.cppblog.com/woaidongmao/archive/2008/11/19/67320.html</link><dc:creator>肥仔</dc:creator><author>肥仔</author><pubDate>Wed, 19 Nov 2008 13:15:00 GMT</pubDate><guid>http://www.cppblog.com/woaidongmao/archive/2008/11/19/67320.html</guid><wfw:comment>http://www.cppblog.com/woaidongmao/comments/67320.html</wfw:comment><comments>http://www.cppblog.com/woaidongmao/archive/2008/11/19/67320.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/woaidongmao/comments/commentRss/67320.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/woaidongmao/services/trackbacks/67320.html</trackback:ping><description><![CDATA[<p></p> <p class="MsoNormal" style="word-break: break-all; line-height: 150%"><span style="font-size: 12pt; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial">虽然平时在程序开发时较少使用<span lang="EN-US" style="color: #990000">union</span><b><span lang="EN-US" style="color: #663300">,</span></b>虽然当初学<span lang="EN-US">C</span>语言时<b><span lang="EN-US" style="color: #663300">,</span></b><span lang="EN-US" style="color: #990000">union</span>一<?xml:namespace prefix = st1 /><st1:personname w:st="on" productid="章被">章被</st1:personname>老师略过没有介绍<b><span lang="EN-US" style="color: #663300">,</span></b>虽然<b><span lang="EN-US" style="color: #663300">,</span></b>自认为自己对<span lang="EN-US" style="color: #990000">union</span>的认识已经足够<b><span lang="EN-US" style="color: #663300">,</span></b>但是<b><span lang="EN-US" style="color: #663300">,</span></b>在写完上一篇文章<span lang="EN-US"><a href="http://blog.vckbase.com/billdavid/archive/2004/11/12/1482.aspx"><b><span style="color: #663300; text-decoration: none; text-underline: none">&lt;(</span></b><span lang="EN-US" style="color: #1d58d1; text-decoration: none; text-underline: none"><span lang="EN-US">大卫的阅读笔记</span></span><b><span style="color: #663300; text-decoration: none; text-underline: none">)</span></b><span style="color: #1d58d1; text-decoration: none; text-underline: none">C</span><b><span style="color: #663300; text-decoration: none; text-underline: none">++</span></b><span lang="EN-US" style="color: #1d58d1; text-decoration: none; text-underline: none"><span lang="EN-US">中使用</span></span><span style="color: #990000; text-decoration: none; text-underline: none">union</span><span lang="EN-US" style="color: #1d58d1; text-decoration: none; text-underline: none"><span lang="EN-US">的几点思考</span></span><b><span style="color: #663300; text-decoration: none; text-underline: none">&gt;</span></b></a></span>之后<b><span lang="EN-US" style="color: #663300">,</span></b>网上的讨论驱使我对这一基本的语言特性又投入了一些精力去关注<b><span lang="EN-US" style="color: #663300">,</span></b>并写成了此文<b><span lang="EN-US" style="color: #663300">.</span></b><span lang="EN-US"><br><br></span>下面以<span lang="EN-US">MSDN</span>中关于<span lang="EN-US" style="color: #990000">union</span>的概述作为开头<b><span lang="EN-US" style="color: #663300">,</span></b>这好像有些无聊<b><span lang="EN-US" style="color: #663300">,</span></b>不过<b><span lang="EN-US" style="color: #663300">,</span></b>有时候看<span lang="EN-US">specification</span>的东西可以给我们很多提示<b><span lang="EN-US" style="color: #663300">,</span></b>当我们从应用的角度去关注一样东西的时候<b><span lang="EN-US" style="color: #663300">,</span></b>很多更深层次的考虑被我们忽略了<b><span lang="EN-US" style="color: #663300">.</span></b>所以<b><span lang="EN-US" style="color: #663300">,</span></b>看下去<b><span lang="EN-US" style="color: #663300">,</span></b>里面有些东西可能正是你忽略了的<b><span lang="EN-US" style="color: #663300">.</span></b><span lang="EN-US" style="color: #990000"><br><br>union<br>union</span><b><span lang="EN-US" style="color: #663300"> [</span></b><span lang="EN-US">tag<b><span style="color: #663300">] {</span></b> member<b><span style="color: #663300">-</span></b>list<b><span style="color: #663300"> } [</span></b>declarators<b><span style="color: #663300">];<br><br>[</span></b><span style="color: #990000">union</span><b><span style="color: #663300">]</span></b> tag declarators<b><span style="color: #663300">;</span></b><br><br>The<span style="color: #990000"> union</span> keyword declares a<span style="color: #990000"> union</span> type<span style="color: #990000"> and</span><b><span style="color: #663300">/</span></b><span style="color: #990000">or</span> a variable of a<span style="color: #990000"> union</span> type<b><span style="color: #663300">.</span></b><br><br>A<span style="color: #990000"> union</span> is a user<b><span style="color: #663300">-</span></b>defined data type that can hold values of different types at different times<b><span style="color: #663300">.</span></b> It is similar to a structure<br>except that all of its members start at the same location in memory<b><span style="color: #663300">.</span></b> A<span style="color: #990000"> union</span> variable can contain only one of its members at<br>a time<b><span style="color: #663300">.</span></b> The size of the<span style="color: #990000"> union</span> is at least the size of the largest member<b><span style="color: #663300">(</span></b></span>大卫注<b><span lang="EN-US" style="color: #663300">:</span></b>我想不出来大于的情况<b><span lang="EN-US" style="color: #663300">).</span></b><span lang="EN-US"><br><br>For related information<b><span style="color: #663300">,</span></b> see<span style="color: #990000"> class</span><b><span style="color: #663300">,</span></b><span style="color: #990000"> struct</span><b><span style="color: #663300">,</span></b><span style="color: #990000"> and</span> Anonymous Union<b><span style="color: #663300">.</span></b><br><br>Declaring a <st1:place w:st="on">Union</st1:place><br><br>Begin the declaration of a<span style="color: #990000"> union</span> with the<span style="color: #990000"> union</span> keyword<b><span style="color: #663300">,</span></b><span style="color: #990000"> and</span> enclose the member list in curly braces<b><span style="color: #663300">:</span></b><span style="color: #990000"><br><br>union</span> UNKNOWN<i><span style="color: #999999">&nbsp;&nbsp;&nbsp; // Declare union type<br></span></i><b><span style="color: #663300">{</span></b><span style="color: #ff6633"><br>&nbsp;&nbsp; char</span>&nbsp;&nbsp; ch<b><span style="color: #663300">;</span></b><span style="color: #ff6633"><br>&nbsp;&nbsp; int</span>&nbsp;&nbsp;&nbsp; i<b><span style="color: #663300">;</span></b><span style="color: #ff6633"><br>&nbsp;&nbsp; long</span>&nbsp;&nbsp; l<b><span style="color: #663300">;</span></b><span style="color: #ff6633"><br>&nbsp;&nbsp; float</span>&nbsp; f<b><span style="color: #663300">;</span></b><span style="color: #ff6633"><br>&nbsp;&nbsp; double</span> d<b><span style="color: #663300">;<br>}</span></b> var1<b><span style="color: #663300">;</span></b><i><span style="color: #999999">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Optional declaration of union variable<br></span></i>Using a <st1:place w:st="on">Union</st1:place><br><br>A C<b><span style="color: #663300">++</span></b><span style="color: #990000"> union</span> is a limited form of the<span style="color: #990000"> class</span> type<b><span style="color: #663300">.</span></b> It can contain access specifiers<b><span style="color: #663300"> (</span></b><span style="color: #990000">public</span><b><span style="color: #663300">,</span></b><span style="color: #990000"> protected</span><b><span style="color: #663300">,</span></b><span style="color: #990000"> private</span><b><span style="color: #663300">),</span></b> member data<b><span style="color: #663300">,</span></b><span style="color: #990000"><br>and</span> member functions<b><span style="color: #663300">,</span></b> including constructors<span style="color: #990000"> and</span> destructors<b><span style="color: #663300">.</span></b> It cannot contain<span style="color: #990000"> virtual</span> functions<span style="color: #990000"> or static</span> data members<b><span style="color: #663300">.</span></b> It<br>cannot be used as a base<span style="color: #990000"> class</span><b><span style="color: #663300">,</span></b> nor can it have base classes<b><span style="color: #663300">.</span></b> Default access of members in a<span style="color: #990000"> union</span> is<span style="color: #990000"> public</span><b><span style="color: #663300">.</span></b><br><br>A C<span style="color: #990000"> union</span> type can contain only data members<b><span style="color: #663300">.</span></b><br><br>In C<b><span style="color: #663300">,</span></b> you must use the<span style="color: #990000"> union</span> keyword to declare a<span style="color: #990000"> union</span> variable<b><span style="color: #663300">.</span></b> In C<b><span style="color: #663300">++,</span></b> the<span style="color: #990000"> union</span> keyword is unnecessary<b><span style="color: #663300">:</span></b><br><br>Example<span style="color: #999900"> 1</span><span style="color: #990000"><br><br>union</span> UNKNOWN var2<b><span style="color: #663300">;</span></b><i><span style="color: #999999">&nbsp;&nbsp; // C declaration of a union variable<br></span></i>UNKNOWN var3<b><span style="color: #663300">;</span></b><i><span style="color: #999999">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // C++ declaration of a union variable<br></span></i>Example<span style="color: #999900"> 2</span><br><br>A variable of a<span style="color: #990000"> union</span> type can hold one value of any type declared in the<span style="color: #990000"> union</span><b><span style="color: #663300">.</span></b> Use the member<b><span style="color: #663300">-</span></b>selection<span style="color: #990000"> operator</span><b><span style="color: #663300"> (.)</span></b> to access a member of a<span style="color: #990000"> union</span><b><span style="color: #663300">:</span></b><br><br>var1<b><span style="color: #663300">.</span></b>i<b><span style="color: #663300"> =</span></b><span style="color: #999900"> 6</span><b><span style="color: #663300">;</span></b><i><span style="color: #999999">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Use variable as integer<br></span></i>var2<b><span style="color: #663300">.</span></b>d<b><span style="color: #663300"> =</span></b><span style="color: #996600"> 5.327</span><b><span style="color: #663300">;</span></b><i><span style="color: #999999">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Use variable as double<br></span></i><br></span>为了避免对上述文字有稍许的歪曲<b><span lang="EN-US" style="color: #663300">,</span></b>我故意没有翻译它<b><span lang="EN-US" style="color: #663300">,</span></b>但在此对其进行一些归纳<b><span lang="EN-US" style="color: #663300">:</span></b><span lang="EN-US" style="color: #996600"><br>1.</span><span lang="EN-US" style="color: #990000">union</span>是一种特殊的<span lang="EN-US" style="color: #990000">struct</span><b><span lang="EN-US" style="color: #663300">/</span></b><span lang="EN-US" style="color: #990000">class</span><b><span lang="EN-US" style="color: #663300">,</span></b>是一种可用于容纳多种类型的类型<b><span lang="EN-US" style="color: #663300">,</span></b>但与<span lang="EN-US" style="color: #990000">struct</span><b><span lang="EN-US" style="color: #663300">/</span></b><span lang="EN-US" style="color: #990000">class</span>不同的是<b><span lang="EN-US" style="color: #663300">,</span></b>所有的成员变量共享同一存储空间<b><span lang="EN-US" style="color: #663300">(</span></b>最大的那一个成员类型的大小<b><span lang="EN-US" style="color: #663300">),</span></b>这使得它具有多变的特性<b><span lang="EN-US" style="color: #663300">,</span></b>可以在不同成员中任意切换<b><span lang="EN-US" style="color: #663300">,</span></b>而无需借助强制类型转换<b><span lang="EN-US" style="color: #663300">,</span></b>但这也使得你不能把它当作一个成员变量进行修改而不影响到另一成员变量<b><span lang="EN-US" style="color: #663300">;</span></b><span lang="EN-US" style="color: #996600"><br>2.</span><span lang="EN-US" style="color: #990000">union</span>也可以有构造<b><span lang="EN-US" style="color: #663300">/</span></b>析构函数<b><span lang="EN-US" style="color: #663300">,</span></b>也可以包含访问标识符<b><span lang="EN-US" style="color: #663300">,</span></b>但不能包含虚函数或静态成员变量<b><span lang="EN-US" style="color: #663300">/</span></b>方法<b><span lang="EN-US" style="color: #663300">.</span></b><span lang="EN-US"><br><br></span>关于使用<span lang="EN-US" style="color: #990000">union</span>时需要注意的一些问题<b><span lang="EN-US" style="color: #663300">,</span></b>可以参考我的前一篇文章<b><span lang="EN-US" style="color: #663300">:&lt;(</span></b>大卫的阅读笔记<b><span lang="EN-US" style="color: #663300">)</span></b><span lang="EN-US">C<b><span style="color: #663300">++</span></b></span>中使用<span lang="EN-US" style="color: #990000">union</span>的几点思考<b><span lang="EN-US" style="color: #663300">&gt;.</span></b><span lang="EN-US"><br></span>下面谈谈一些比较有意思并且有意义的<span lang="EN-US" style="color: #990000">union</span>的应用<b><span lang="EN-US" style="color: #663300">.</span></b><span lang="EN-US" style="color: #996600"><br>1.</span><span lang="EN-US">in_addr<span style="color: #990000"><br><br>struct</span> in_addr<b><span style="color: #663300"> {</span></b><span style="color: #990000"><br>&nbsp; union</span><b><span style="color: #663300"> {</span></b><span style="color: #990000"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct</span><b><span style="color: #663300"> {</span></b> u_char s_b1<b><span style="color: #663300">,</span></b>s_b2<b><span style="color: #663300">,</span></b>s_b3<b><span style="color: #663300">,</span></b>s_b4<b><span style="color: #663300">; }</span></b>&nbsp;&nbsp; S_un_b<b><span style="color: #663300">;</span></b><span style="color: #990000"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct</span><b><span style="color: #663300"> {</span></b> u_short s_w1<b><span style="color: #663300">,</span></b>s_w2<b><span style="color: #663300">; }</span></b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; S_un_w<b><span style="color: #663300">;</span></b><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u_long&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; S_addr<b><span style="color: #663300">;<br>&nbsp; }</span></b> S_un<b><span style="color: #663300">;<br>};</span></b><br><br></span>对于上面的<span lang="EN-US" style="color: #990000">struct</span><b><span lang="EN-US" style="color: #663300">,</span></b>写过<span lang="EN-US">socket</span>应用的人<b><span lang="EN-US" style="color: #663300">,</span></b>肯定都用过它<b><span lang="EN-US" style="color: #663300">.</span></b>不知你注意过没有<b><span lang="EN-US" style="color: #663300">,</span></b>它包含了一个很有趣的<span lang="EN-US" style="color: #990000">union</span><b><span lang="EN-US" style="color: #663300">,</span></b>该<span lang="EN-US" style="color: #990000">union</span>的各成员具有相同的大小<b><span lang="EN-US" style="color: #663300">,</span></b>分别代表同一信息的不同表现形式<b><span lang="EN-US" style="color: #663300">.</span></b>你在进行程序设计的时候也可以利用这一特性来提供同一信息的不同表现形式<b><span lang="EN-US" style="color: #663300">,</span></b>不过要注意<b><span lang="EN-US" style="color: #663300">,</span></b>在进行跨平台应用时<b><span lang="EN-US" style="color: #663300">,</span></b>字节顺序的影响可能给你造成一些不必要的麻烦<b><span lang="EN-US" style="color: #663300">.</span></b><span lang="EN-US" style="color: #996600"><br><br>2.</span>匿名<span lang="EN-US" style="color: #990000">union</span><span lang="EN-US"><br></span>匿名<span lang="EN-US" style="color: #990000">union</span>是没有名称和声明列表的<span lang="EN-US" style="color: #990000">union</span><b><span lang="EN-US" style="color: #663300">,</span></b>这跟<span lang="EN-US" style="color: #009900">'__unnamed'</span><span lang="EN-US" style="color: #990000"> union</span>不是一回事<b><span lang="EN-US" style="color: #663300">,</span></b>它的声明形式如下<b><span lang="EN-US" style="color: #663300">:</span></b><span lang="EN-US" style="color: #990000"><br>union</span><b><span lang="EN-US" style="color: #663300"> {</span></b><span lang="EN-US"> member<b><span style="color: #663300">-</span></b>list<b><span style="color: #663300"> } ;</span></b><br><br></span>匿名<span lang="EN-US" style="color: #990000">union</span>仅仅通知编译器它的成员变量共享一个地址<b><span lang="EN-US" style="color: #663300">,</span></b>而变量本身是直接引用的<b><span lang="EN-US" style="color: #663300">,</span></b>不使用通常的点号运算符语法<b><span lang="EN-US" style="color: #663300">.</span></b>也正因此<b><span lang="EN-US" style="color: #663300">,</span></b>匿名<span lang="EN-US" style="color: #990000">union</span>与同一程序块内的其它变量具有相同的作用域级别<b><span lang="EN-US" style="color: #663300">,</span></b>需注意命名冲突<b><span lang="EN-US" style="color: #663300">.</span></b><span lang="EN-US"><br></span>请看下面的例子<b><span lang="EN-US" style="color: #663300">:</span></b><span lang="EN-US" style="color: #000099"><br><br>#include &lt;iostream.h&gt;<br></span><span lang="EN-US" style="color: #990000"><br>struct</span><span lang="EN-US"> DataForm<b><span style="color: #663300"><br>{</span></b><span style="color: #990000"><br>&nbsp;&nbsp;&nbsp; enum</span> DataType<b><span style="color: #663300"> {</span></b> CharData<b><span style="color: #663300"> =</span></b><span style="color: #999900"> 1</span><b><span style="color: #663300">,</span></b> IntData<b><span style="color: #663300">,</span></b> StringData<b><span style="color: #663300"> };</span></b><br>&nbsp;&nbsp;&nbsp; DataType type<b><span style="color: #663300">;</span></b><i><span style="color: #999999"><br><br>&nbsp;&nbsp;&nbsp; // Declare an anonymous union.<br></span></i><span style="color: #990000">&nbsp;&nbsp;&nbsp; union</span><b><span style="color: #663300"><br>&nbsp;&nbsp;&nbsp; {</span></b><span style="color: #ff6633"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; char</span>&nbsp; chCharMem<b><span style="color: #663300">;</span></b><span style="color: #ff6633"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; char</span><b><span style="color: #663300"> *</span></b>szStrMem<b><span style="color: #663300">;</span></b><span style="color: #ff6633"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int</span>&nbsp;&nbsp; iIntMem<b><span style="color: #663300">;<br>&nbsp;&nbsp;&nbsp; };</span></b><span style="color: #ff6633"><br>&nbsp;&nbsp;&nbsp; void</span> print<b><span style="color: #663300">();<br>};</span></b><span style="color: #ff6633"><br><br>void</span> DataForm<b><span style="color: #663300">::</span></b>print<b><span style="color: #663300">()<br>{</span></b><i><span style="color: #999999"><br>&nbsp;&nbsp; </span><span style="color: black"> // Based on the type of the data, print the<br>&nbsp;&nbsp;&nbsp; // appropriate data type.<br></span></i><span style="color: red">&nbsp;&nbsp;&nbsp; switch</span><b><span style="color: #663300">(</span></b> type<b><span style="color: #663300"> )<br>&nbsp;&nbsp;&nbsp; {</span></b><span style="color: red"><br>&nbsp;&nbsp;&nbsp; case</span> CharData<b><span style="color: #663300">:</span></b><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cout<b><span style="color: #663300"> &lt;&lt;</span></b> chCharMem<b><span style="color: #663300">;</span></b><span style="color: red"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break</span><b><span style="color: #663300">;</span></b><span style="color: red"><br>&nbsp;&nbsp;&nbsp; case</span> IntData<b><span style="color: #663300">:</span></b><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cout<b><span style="color: #663300"> &lt;&lt;</span></b> szStrMem<b><span style="color: #663300">;</span></b><span style="color: red"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break</span><b><span style="color: #663300">;</span></b><span style="color: red"><br>&nbsp;&nbsp;&nbsp; case</span> StringData<b><span style="color: #663300">:</span></b><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cout<b><span style="color: #663300"> &lt;&lt;</span></b> iIntMem<b><span style="color: #663300">;</span></b><span style="color: red"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break</span><b><span style="color: #663300">;<br>&nbsp;&nbsp;&nbsp; }<br>}</span></b><br><br></span>此外<b><span lang="EN-US" style="color: #663300">,</span></b>匿名<span lang="EN-US" style="color: #990000">union</span>还具有以下约束<b><span lang="EN-US" style="color: #663300">:</span></b><span lang="EN-US" style="color: #999900"><br>1</span><b><span lang="EN-US" style="color: #663300">).</span></b>因为匿名联合不使用点运算符<b><span lang="EN-US" style="color: #663300">,</span></b>所以包含在匿名联合内的元素必须是数据<b><span lang="EN-US" style="color: #663300">,</span></b>不允许有成员函数<b><span lang="EN-US" style="color: #663300">,</span></b>也不能包含私有或受保护的成员<b><span lang="EN-US" style="color: #663300">;</span></b><span lang="EN-US" style="color: #999900"><br>2</span><b><span lang="EN-US" style="color: #663300">).</span></b>全局匿名联合必须是静态<b><span lang="EN-US" style="color: #663300">(</span></b><span lang="EN-US" style="color: #990000">static</span><b><span lang="EN-US" style="color: #663300">)</span></b>的，否则就必须放在匿名名字空间中<b><span lang="EN-US" style="color: #663300">.</span></b><span lang="EN-US"><br><br></span>附注<b><span lang="EN-US" style="color: #663300">:</span></b><span lang="EN-US"><br></span>对匿名<span lang="EN-US" style="color: #990000">union</span>的概念<b><span lang="EN-US" style="color: #663300">,</span></b>你或许有些陌生<b><span lang="EN-US" style="color: #663300">,</span></b>但对于<span lang="EN-US">Windows</span>应用的开发人员<b><span lang="EN-US" style="color: #663300">,</span></b>有一个经常用到的结构中就包含了匿名<span lang="EN-US" style="color: #990000">union</span><b><span lang="EN-US" style="color: #663300">,</span></b>它就是<span lang="EN-US">VARIANT<b><span style="color: #663300">,</span></b></span>也许你没有注意它罢了<b><span lang="EN-US" style="color: #663300">:</span></b><span lang="EN-US" style="color: #990000"><br><br>typedef struct</span><span lang="EN-US"> FARSTRUCT tagVARIANT VARIANT<b><span style="color: #663300">;</span></b><span style="color: #990000"><br>typedef struct</span> FARSTRUCT tagVARIANT VARIANTARG<b><span style="color: #663300">;</span></b><span style="color: #990000"><br><br>typedef struct</span> tagVARIANT<b><span style="color: #663300">&nbsp; {</span></b><br>&nbsp;&nbsp; VARTYPE vt<b><span style="color: #663300">;</span></b><span style="color: #ff6633"><br>&nbsp;&nbsp; unsigned short</span> wReserved1<b><span style="color: #663300">;</span></b><span style="color: #ff6633"><br>&nbsp;&nbsp; unsigned short</span> wReserved2<b><span style="color: #663300">;</span></b><span style="color: #ff6633"><br>&nbsp;&nbsp; unsigned short</span> wReserved3<b><span style="color: #663300">;</span></b><span style="color: #990000"><br>&nbsp;&nbsp; union</span><b><span style="color: #663300"> {</span></b><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Byte&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bVal<b><span style="color: #663300">;</span></b><i><span style="color: #999999">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // VT_UI1.<br></span></i>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Short&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; iVal<b><span style="color: #663300">;</span></b><i><span style="color: #999999">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // VT_I2.<br></span></i><span style="color: #ff6633">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; long</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; lVal<b><span style="color: #663300">;</span></b><i><span style="color: #999999">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // VT_I4.<br></span></i><span style="color: #ff6633">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; float</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fltVal<b><span style="color: #663300">;</span></b><i><span style="color: #999999">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // VT_R4.<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // ...<br></span></i><b><span style="color: #663300">&nbsp;&nbsp; };<br>};</span></b><span style="color: #996600"><br><br>3.</span></span>利用<span lang="EN-US" style="color: #990000">union</span>进行类型转换<span lang="EN-US"><br></span>前面已经说过<b><span lang="EN-US" style="color: #663300">,</span></b><span lang="EN-US" style="color: #990000">union</span>具有多变的特性<b><span lang="EN-US" style="color: #663300">,</span></b>可以在不同成员中任意切换<b><span lang="EN-US" style="color: #663300">,</span></b>而无需借助强制类型转换<b><span lang="EN-US" style="color: #663300">,</span></b>下面举例说明这一点<b><span lang="EN-US" style="color: #663300">(</span></b>其实<span lang="EN-US" style="color: #999900">1</span>已经很好地说明了这一点<b><span lang="EN-US" style="color: #663300">):</span></b><span lang="EN-US" style="color: #000099"><br><br>#include &lt;iostream&gt;<br></span><span lang="EN-US" style="color: #990000">using namespace</span><span lang="EN-US"> std<b><span style="color: #663300">;</span></b><span style="color: #990000"><br><br>struct</span> DATA<b><span style="color: #663300"><br>{</span></b><span style="color: #ff6633"><br>&nbsp;&nbsp;&nbsp; char</span> c1<b><span style="color: #663300">;</span></b><span style="color: #ff6633"><br>&nbsp;&nbsp;&nbsp; char</span> c2<b><span style="color: #663300">;<br>};</span></b><span style="color: #ff6633"><br><br>int</span><span style="color: #990000"> main</span><b><span style="color: #663300">()<br>{</span></b><span style="color: #990000"><br>&nbsp;&nbsp;&nbsp; union</span><b><span style="color: #663300"> {</span></b><span style="color: #ff6633">&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int</span> i<b><span style="color: #663300">;</span></b>&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DATA data<b><span style="color: #663300">; <br>&nbsp;&nbsp;&nbsp; }</span></b> _ut<b><span style="color: #663300">;</span></b><br>&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; _ut<b><span style="color: #663300">.</span></b>i<b><span style="color: #663300"> =</span></b><span style="color: #999900"> 0x6162</span><b><span style="color: #663300">;</span></b><br><br>&nbsp;&nbsp;&nbsp; cout<b><span style="color: #663300"> &lt;&lt;</span></b><span style="color: #009900"> "_ut.data.c1 = "</span><b><span style="color: #663300"> &lt;&lt;</span></b> _ut<b><span style="color: #663300">.</span></b>data<b><span style="color: #663300">.</span></b>c1<b><span style="color: #663300"> &lt;&lt;</span></b> endl<b><span style="color: #663300"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;&lt;</span></b><span style="color: #009900"> "_ut.data.c2 = "</span><b><span style="color: #663300"> &lt;&lt;</span></b> _ut<b><span style="color: #663300">.</span></b>data<b><span style="color: #663300">.</span></b>c2<b><span style="color: #663300"> &lt;&lt;</span></b> endl<b><span style="color: #663300">;</span></b><span style="color: red"><br>&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; return</span><span style="color: #999900"> 0</span><b><span style="color: #663300">;<br>}</span></b><br><br></span>需要提醒你的是<b><span lang="EN-US" style="color: #663300">,</span></b>数据类型的转换<b><span lang="EN-US" style="color: #663300">,</span></b>并非<span lang="EN-US" style="color: #990000">union</span>的专长<b><span lang="EN-US" style="color: #663300">,</span></b>只是一个可资利用的特性而已<b><span lang="EN-US" style="color: #663300">.</span></b>因为<b><span lang="EN-US" style="color: #663300">,</span></b>采用<span lang="EN-US" style="color: #990000">union</span>进行类型间转换极易受平台影响<b><span lang="EN-US" style="color: #663300">,</span></b>如上面的程序采用<span lang="EN-US">Intel x86<b><span style="color: #663300"> +</span></b> Windows<span style="color: #999900"> 2000</span><b><span style="color: #663300"> +</span></b> VC6</span>时输出为<b><span lang="EN-US" style="color: #663300">:</span></b><span lang="EN-US"><br>_ut<b><span style="color: #663300">.</span></b>data<b><span style="color: #663300">.</span></b>c1<b><span style="color: #663300"> =</span></b> b<br>_ut<b><span style="color: #663300">.</span></b>data<b><span style="color: #663300">.</span></b>c2<b><span style="color: #663300"> =</span></b> a<b><span style="color: #663300"><br>(</span></b></span>注<b><span lang="EN-US" style="color: #663300">:</span></b>因为<span lang="EN-US">Intel CPU</span>的架构是<span lang="EN-US">Little Endian<b><span style="color: #663300">)</span></b><br></span>而在<span lang="EN-US">Sun</span>的<span lang="EN-US">Sparc</span>上<b><span lang="EN-US" style="color: #663300">,</span></b>你得到的结果却是<b><span lang="EN-US" style="color: #663300">:</span></b><span lang="EN-US"><br>_ut<b><span style="color: #663300">.</span></b>data<b><span style="color: #663300">.</span></b>c1<b><span style="color: #663300"> =</span></b>&nbsp;<br>_ut<b><span style="color: #663300">.</span></b>data<b><span style="color: #663300">.</span></b>c2<b><span style="color: #663300"> = <br>(</span></b></span>注<b><span lang="EN-US" style="color: #663300">:</span></b>因为采用<span lang="EN-US">Big Endian</span>时<b><span lang="EN-US" style="color: #663300">,</span></b>前两个字节为<span lang="EN-US" style="color: #999900">0x0000</span><b><span lang="EN-US" style="color: #663300">)</span></b><span lang="EN-US"><br><br></span>而即便是在同一平台上<b><span lang="EN-US" style="color: #663300">,</span></b>在<span lang="EN-US">integer</span>类型与<span lang="EN-US">real</span>类型间进行转换时也不要采用<span lang="EN-US" style="color: #990000">union</span><b><span lang="EN-US" style="color: #663300">,</span></b>否则<b><span lang="EN-US" style="color: #663300">,</span></b>你会得到令你莫名其妙的结论<b><span lang="EN-US" style="color: #663300">(</span></b>这是由于<span lang="EN-US">CPU</span>对<span lang="EN-US">real</span>类型的处理方式引起的<b><span lang="EN-US" style="color: #663300">,</span></b>该方式在各平台上有极大区别<b><span lang="EN-US" style="color: #663300">,</span></b>同时<b><span lang="EN-US" style="color: #663300">,</span></b>根据<span lang="EN-US">C<b><span style="color: #663300">++</span></b> Standard<b><span style="color: #663300">,</span></b></span>这种作法会引起<span lang="EN-US" style="color: #009900">"undefined behavior"</span><b><span lang="EN-US" style="color: #663300">).</span></b><span lang="EN-US"><br><br></span>关于利用引用进行类型转换<b><span lang="EN-US" style="color: #663300">,</span></b>可参考<span lang="EN-US"><a href="http://blog.vckbase.com/bruceteen/archive/2004/06/18/486.aspx" target="_blank"><b><span style="color: #663300; text-decoration: none; text-underline: none">&lt;</span></b><span lang="EN-US" style="color: #1d58d1; text-decoration: none; text-underline: none"><span lang="EN-US">引用在强制类型转化<span lang="EN-US">中<span lang="EN-US">的应用</span></span></span></span><b><span style="color: #663300; text-decoration: none; text-underline: none">&gt;</span></b></a><b><span style="color: #663300">.</span></b> <?xml:namespace prefix = o /><o:p></o:p></span></span></p> <p class="MsoNormal" style="word-break: break-all; line-height: 150%"><span lang="EN-US" style="font-size: 12pt; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial"><o:p>&nbsp;</o:p></span></p> <div style="border-right: medium none; padding-right: 0cm; border-top: #dddddd 1pt solid; padding-left: 0cm; padding-bottom: 0cm; border-left: medium none; padding-top: 0cm; border-bottom: medium none; mso-element: para-border-div; mso-border-top-alt: solid #dddddd .75pt"> <p class="postfoot2" style="word-break: break-all; line-height: 150%"><span lang="EN-US" style="font-size: 12pt; line-height: 150%; mso-bidi-font-family: arial">posted on 2004-11-26 10:16 </span><span style="font-size: 12pt; line-height: 150%; mso-bidi-font-family: arial">大卫的思维空间 阅读<span lang="EN-US">(3750) <a href="http://blog.vckbase.com/billdavid/archive/2004/11/26/1759.aspx#Post#Post"><span lang="EN-US"><span lang="EN-US">评论(8)</span></span></a>&nbsp; <a href="http://blog.vckbase.com/billdavid/admin/EditPosts.aspx?postid=1759"><span lang="EN-US"><span lang="EN-US">编辑</span></span></a>&nbsp;<a href="http://blog.vckbase.com/billdavid/AddToFavorite.aspx?id=1759"><span lang="EN-US"><span lang="EN-US">收藏</span></span></a> <o:p></o:p></span></span></p></div> <div style="border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; padding-bottom: 0cm; margin-left: 7.5pt; border-left: medium none; margin-right: 7.5pt; padding-top: 0cm; border-bottom: #aaaaaa 1pt solid; mso-element: para-border-div; mso-border-bottom-alt: solid #aaaaaa .75pt"> <p class="MsoNormal" style="border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; padding-bottom: 0cm; border-left: medium none; word-break: break-all; padding-top: 0cm; border-bottom: medium none; mso-border-bottom-alt: solid #aaaaaa .75pt; mso-outline-level: 4; mso-padding-alt: 0cm 0cm 0cm 0cm"><a name="评论"><b><span style="font-size: 12pt; color: #223355; font-family: 宋体; mso-bidi-font-family: arial"><link href="http://blog.vckbase.com/billdavid/Services/Pingback.aspx" rel="pingback">评论<span lang="EN-US"><o:p></o:p></span></span></b></a></p></div><span style="mso-bookmark: 评论"></span> <p class="MsoNormal" style="margin-bottom: 3pt; word-break: break-all; line-height: 150%; mso-outline-level: 3"><b><span lang="EN-US" style="font-size: 12pt; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial"><a title="permalink: re: 对union的进一步认识与一些深层应用" href="http://blog.vckbase.com/billdavid/archive/2004/11/26/1759.html#1761">#</a>&nbsp;<a name="1761"></a>re: </span></b><b><span style="font-size: 12pt; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial">对<span lang="EN-US">union</span>的进一步认识与一些深层应用 <span lang="EN-US"><a id="Comments1_CommentList__ctl0_EditLink" href=""></a><o:p></o:p></span></span></b></p> <p class="MsoNormal" style="word-break: break-all; line-height: 150%"><span lang="EN-US" style="font-size: 12pt; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial">“</span><span style="font-size: 12pt; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial">我想不出来大于的情况<span lang="EN-US">” <br>--- </span>还有字节对齐的情况，和<span lang="EN-US">struct</span>一样<span lang="EN-US"> <br><br></span>匿名<span lang="EN-US">union</span>我经常使用，但我不知道它叫<span lang="EN-US">“</span>匿名<span lang="EN-US">union”</span>，而且还可以放在外边用，我去试试看，谢谢！ <span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal" style="word-break: break-all; line-height: 150%"><span lang="EN-US" style="font-size: 12pt; color: #aaaaaa; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial">2004-11-26 22:07 | <a id="Comments1_CommentList__ctl0_NameLink" href="http://blog.vckbase.com/bruceteen" target="_blank"><span lang="EN-US"><span lang="EN-US">周星星</span></span></a> <o:p></o:p></span></p> <p class="MsoNormal" style="margin-bottom: 3pt; word-break: break-all; line-height: 150%; mso-outline-level: 3"><b><span lang="EN-US" style="font-size: 12pt; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial"><a title="permalink: re: 对union的进一步认识与一些深层应用" href="http://blog.vckbase.com/billdavid/archive/2004/11/26/1759.html#5135">#</a>&nbsp;<a name="5135"></a>re: </span></b><b><span style="font-size: 12pt; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial">对<span lang="EN-US">union</span>的进一步认识与一些深层应用 <span lang="EN-US"><a id="Comments1_CommentList__ctl1_EditLink" href=""></a><o:p></o:p></span></span></b></p> <p class="MsoNormal" style="word-break: break-all; line-height: 150%"><span style="font-size: 12pt; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial">你的文章写的很好<span lang="EN-US">,</span>总结得不错 <span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal" style="word-break: break-all; line-height: 150%"><span lang="EN-US" style="font-size: 12pt; color: #aaaaaa; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial">2005-05-05 13:34 | peak <o:p></o:p></span></p> <p class="MsoNormal" style="margin-bottom: 3pt; word-break: break-all; line-height: 150%; mso-outline-level: 3"><b><span lang="EN-US" style="font-size: 12pt; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial"><a title="permalink: re: 对union的进一步认识与一些深层应用" href="http://blog.vckbase.com/billdavid/archive/2004/11/26/1759.html#14254">#</a>&nbsp;<a name="14254"></a>re: </span></b><b><span style="font-size: 12pt; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial">对<span lang="EN-US">union</span>的进一步认识与一些深层应用 <span lang="EN-US"><a id="Comments1_CommentList__ctl2_EditLink" href=""></a><o:p></o:p></span></span></b></p> <p class="MsoNormal" style="word-break: break-all; line-height: 150%"><span lang="EN-US" style="font-size: 12pt; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial">union</span><span style="font-size: 12pt; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial">实际上是一个二进制容器，所以当程序中从不同的角度来解释这个二进制数据的时候非常容易受各种实现细节的影响，尤其是涉及到这些二进制数据在不同平台和编译器之间交换的时候。 <span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal" style="word-break: break-all; line-height: 150%"><span lang="EN-US" style="font-size: 12pt; color: #aaaaaa; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial">2005-10-29 00:51 | <a id="Comments1_CommentList__ctl2_NameLink" href="http://spaces.msn.com/members/youngs45" target="_blank">youngs</a> <o:p></o:p></span></p> <p class="MsoNormal" style="margin-bottom: 3pt; word-break: break-all; line-height: 150%; mso-outline-level: 3"><b><span lang="EN-US" style="font-size: 12pt; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial"><a title="permalink: re: 对union的进一步认识与一些深层应用" href="http://blog.vckbase.com/billdavid/archive/2004/11/26/1759.html#31275">#</a>&nbsp;<a name="31275"></a>re: </span></b><b><span style="font-size: 12pt; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial">对<span lang="EN-US">union</span>的进一步认识与一些深层应用 <span lang="EN-US"><a id="Comments1_CommentList__ctl3_EditLink" href=""></a><o:p></o:p></span></span></b></p> <p class="MsoNormal" style="word-break: break-all; line-height: 150%"><span style="font-size: 12pt; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial">多谢文章。请教问题：<span lang="EN-US">union</span>中的成员类型只能是基本的类型，不能使自己定义的类结构么？<span lang="EN-US">&nbsp;</span>比如说<span lang="EN-US"> CMyLine m_Ln? <o:p></o:p></span></span></p> <p class="MsoNormal" style="word-break: break-all; line-height: 150%"><span lang="EN-US" style="font-size: 12pt; color: #aaaaaa; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial">2007-12-13 11:52 | cc <o:p></o:p></span></p> <p class="MsoNormal" style="margin-bottom: 3pt; word-break: break-all; line-height: 150%; mso-outline-level: 3"><b><span lang="EN-US" style="font-size: 12pt; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial"><a title="permalink: re: 对union的进一步认识与一些深层应用" href="http://blog.vckbase.com/billdavid/archive/2004/11/26/1759.html#32839">#</a>&nbsp;<a name="32839"></a>re: </span></b><b><span style="font-size: 12pt; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial">对<span lang="EN-US">union</span>的进一步认识与一些深层应用 <span lang="EN-US"><a id="Comments1_CommentList__ctl4_EditLink" href=""></a><o:p></o:p></span></span></b></p> <p class="MsoNormal" style="word-break: break-all; line-height: 150%"><span lang="EN-US" style="font-size: 12pt; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial">union</span><span style="font-size: 12pt; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial">既然可以包含<span lang="EN-US">struct</span>，自然也是可以包含从<span lang="EN-US">class</span>的，但是存在诸多限制，同时，很难想象你的应用需要在<span lang="EN-US">union</span>中包含一个复杂<span lang="EN-US">class</span>，如<span lang="EN-US">CString</span>或<span lang="EN-US">STL</span>的<span lang="EN-US">string</span>。 <span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal" style="word-break: break-all; line-height: 150%"><span lang="EN-US" style="font-size: 12pt; color: #aaaaaa; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial">2008-03-03 15:44 | <a id="Comments1_CommentList__ctl4_NameLink" href="http://blog.vckbase.com/billdavid" target="_blank"><span lang="EN-US"><span lang="EN-US">大卫的思维空间</span></span></a> <o:p></o:p></span></p> <p class="MsoNormal"><span lang="EN-US" style="font-size: 12pt; font-family: 宋体; mso-bidi-font-family: arial"><o:p>&nbsp;</o:p></span></p> <p class="MsoNormal"><span lang="EN-US" style="font-size: 12pt; font-family: 宋体; mso-bidi-font-family: arial"><o:p>&nbsp;</o:p></span></p><img src ="http://www.cppblog.com/woaidongmao/aggbug/67320.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/woaidongmao/" target="_blank">肥仔</a> 2008-11-19 21:15 <a href="http://www.cppblog.com/woaidongmao/archive/2008/11/19/67320.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>char []越界, 导致EnterCriticalSection异常</title><link>http://www.cppblog.com/woaidongmao/archive/2008/11/19/67295.html</link><dc:creator>肥仔</dc:creator><author>肥仔</author><pubDate>Wed, 19 Nov 2008 07:38:00 GMT</pubDate><guid>http://www.cppblog.com/woaidongmao/archive/2008/11/19/67295.html</guid><wfw:comment>http://www.cppblog.com/woaidongmao/comments/67295.html</wfw:comment><comments>http://www.cppblog.com/woaidongmao/archive/2008/11/19/67295.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/woaidongmao/comments/commentRss/67295.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/woaidongmao/services/trackbacks/67295.html</trackback:ping><description><![CDATA[<p>private:<br>&nbsp;&nbsp;&nbsp; char&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; m_szLog[512];</p> <p>CRITICAL_SECTION m_CS;</p><img src ="http://www.cppblog.com/woaidongmao/aggbug/67295.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/woaidongmao/" target="_blank">肥仔</a> 2008-11-19 15:38 <a href="http://www.cppblog.com/woaidongmao/archive/2008/11/19/67295.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>class内定义的enum和typedef若为private，则外部不可引用</title><link>http://www.cppblog.com/woaidongmao/archive/2008/11/19/67294.html</link><dc:creator>肥仔</dc:creator><author>肥仔</author><pubDate>Wed, 19 Nov 2008 07:33:00 GMT</pubDate><guid>http://www.cppblog.com/woaidongmao/archive/2008/11/19/67294.html</guid><wfw:comment>http://www.cppblog.com/woaidongmao/comments/67294.html</wfw:comment><comments>http://www.cppblog.com/woaidongmao/archive/2008/11/19/67294.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/woaidongmao/comments/commentRss/67294.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/woaidongmao/services/trackbacks/67294.html</trackback:ping><description><![CDATA[<p>如题</p><img src ="http://www.cppblog.com/woaidongmao/aggbug/67294.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/woaidongmao/" target="_blank">肥仔</a> 2008-11-19 15:33 <a href="http://www.cppblog.com/woaidongmao/archive/2008/11/19/67294.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>sizeof可以对STL里面的元素运算</title><link>http://www.cppblog.com/woaidongmao/archive/2008/11/19/67291.html</link><dc:creator>肥仔</dc:creator><author>肥仔</author><pubDate>Wed, 19 Nov 2008 07:27:00 GMT</pubDate><guid>http://www.cppblog.com/woaidongmao/archive/2008/11/19/67291.html</guid><wfw:comment>http://www.cppblog.com/woaidongmao/comments/67291.html</wfw:comment><comments>http://www.cppblog.com/woaidongmao/archive/2008/11/19/67291.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/woaidongmao/comments/commentRss/67291.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/woaidongmao/services/trackbacks/67291.html</trackback:ping><description><![CDATA[<p>int nSize = sizeof(m_vecPOD[s].tolerance_name);</p><img src ="http://www.cppblog.com/woaidongmao/aggbug/67291.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/woaidongmao/" target="_blank">肥仔</a> 2008-11-19 15:27 <a href="http://www.cppblog.com/woaidongmao/archive/2008/11/19/67291.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>VC++的链接错误LNK2005</title><link>http://www.cppblog.com/woaidongmao/archive/2008/11/16/67070.html</link><dc:creator>肥仔</dc:creator><author>肥仔</author><pubDate>Sun, 16 Nov 2008 12:57:00 GMT</pubDate><guid>http://www.cppblog.com/woaidongmao/archive/2008/11/16/67070.html</guid><wfw:comment>http://www.cppblog.com/woaidongmao/comments/67070.html</wfw:comment><comments>http://www.cppblog.com/woaidongmao/archive/2008/11/16/67070.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/woaidongmao/comments/commentRss/67070.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/woaidongmao/services/trackbacks/67070.html</trackback:ping><description><![CDATA[<form id="Form1" name="Form1" action="http://www.cppblog.com/5913.html" method="post" _initialAction="5913.html"> <div id="centercontent"> <div class="post"> <p><font color="#800080"><br></font><font color="#ffa500" size="2">作者: Jerry Cat<br>时间: 2006/04/19<br>链接: http://www.cppblog.com/jerysun0818/archive/2006/04/19/5913.html</font> </p> <p><font size="2">编程中经常能遇到LNK2005错误——重复定义错误，其实LNK2005错误并不是一个很难解决的错误。弄清楚它形成的原因，就可以轻松解决它了。</font> </p> <p><font size="2">造成LNK2005错误主要有以下几种情况：<br>1．重复定义全局变量。可能存在两种情况：<br>A、对于一些初学编程的程序员，有时候会以为需要使用全局变量的地方就可以使用定义申明一下。其实这是错误的，全局变量是针对整个工程的。正确的应该是在一个CPP文件中定义如下：int g_Test;那么在使用的CPP文件中就应该使用：extern int g_Test即可，如果还是使用int g_Test，那么就会产生LNK2005错误，一般错误错误信息类似：AAA.obj error LNK2005 int book c？</font> <a href="mailto:book@@3HA"><font size="2">book@@3HA</font> </a><font size="2">already defined in BBB.obj。切记的就是不能给变量赋值否则还是会有LNK2005错误。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 这里需要的是“声明”，不是“定义”！根据C++标准的规定，一个变量是声明，必须同时满足两个条件，否则就是定义：<br>(1)声明必须使用extern关键字；(2)不能给变量赋初值<br><font color="#ff0000">所以，下面的是声明:<br>extern int a;</font><br><font color="#ff0000">下面的是定义<br>int a; int a = 0; extern int a =0;</font><br>B、对于那么编程不是那么严谨的程序员，总是在需要使用变量的文件中随意定义一个全局变量，并且对于变量名也不予考虑，这也往往容易造成变量名重复，而造成LNK2005错误。</font> </p> <p><font size="2">2．头文件的包含重复。往往需要包含的头文件中含有变量、函数、类的定义，在其它使用的地方又不得不多次包含之，如果头文件中没有相关的宏等防止重复链接的措施，那么就会产生LNK2005错误。解决办法是在需要包含的头文件中做类似的处理：#ifndef MY_H_FILE&nbsp;&nbsp; //如果没有定义这个宏<br>#define MY_H_FILE&nbsp;&nbsp; //定义这个宏<br>…….&nbsp;&nbsp; //头文件主体内容<br>…….<br>#endif<br>上面是使用宏来做的，也可以使用预编译来做，在头文件中加入：<br>#pragma once<br>//头文件主体<br>3．使用第三方的库造成的。这种情况主要是C运行期函数库和MFC的库冲突造成的。具体的办法就是将那个提示出错的库放到另外一个库的前面。另外选择不同的C函数库，可能会引起这个错误。微软和C有两种C运行期函数库，一种是普通的函数库：LIBC.LIB，不支持多线程。另外一种是支持多线程的：msvcrt.lib。如果一个工程里，这两种函数库混合使用，可能会引起这个错误，一般情况下它需要MFC的库先于C运行期函数库被链接，因此建议使用支持多线程的msvcrt.lib。所以在使用第三方的库之前首先要知道它链接的是什么库，否则就可能造成LNK2005错误。如果不得不使用第三方的库，可以尝试按下面所说的方法修改，但不能保证一定能解决问题，前两种方法是微软提供的：<br>A、选择VC菜单Project-&gt;Settings-&gt;Link-&gt;Catagory选择Input，再在Ignore libraries 的Edit栏中填入你需要忽略的库，如：Nafxcwd.lib;Libcmtd.lib。然后在Object/library Modules的Edit栏中填入正确的库的顺序，这里需要你能确定什么是正确的顺序，呵呵，God bless you！<br>B、选择VC菜单Project-&gt;Settings-&gt;Link页，然后在Project Options的Edit栏中输入/verbose:lib，这样就可以在编译链接程序过程中在输出窗口看到链接的顺序了。<br>C、选择VC菜单Project-&gt;Settings-&gt;C/C++页，Catagory选择Code Generation后再在User Runtime libraray中选择MultiThread DLL等其他库，逐一尝试。</font> </p> <p><font size="2">这就是我所遇到过的LNK2005错误的几种情况，肯定还有其他的情况也可能造成这种错误，所以我不希望你在看完这篇文章以后，再遇到LNK2005错误时候，不动脑筋的想对号入座的排除错误。编程的过程就是一个思考的过程，所以还是多多开动你的头脑，那样收获会更多！<br>＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝<br>支持,我在社区里也看到了许多LINK 2005错<br>补充一点,就是一次在用第三方库时,由于errno被重定义,用多种方法都不能解决,后查找MSDN,发现link有个选项/FORCE可以解决,在IDE下<br>Project-&gt;Settings-&gt;Link页,选categroy为custom,将force file output前打勾<br>但会有警告<br>warning LNK4088: image being generated due to /FORCE option; image may not run<br>但的确解决了问题,这是由于VC对重定义比较严格,像BCB或GCC在库中的重定义不会有任何警告或错误<br>＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝<br>我发现的另外一个出现LINK2005的现象，好像是由于名称空间而引起的。我在dos下写的程序没有问题，但是放在mfc中就出现了这个链接错误。因为起初图省事，我在一个头文件中写了using namespace std,并且这个头文件我多处使用，另外，我还使用了boost库。后来，问题解决的方法非常奇怪，在一个头文件中引用其他头文件，这些头文件的顺序换一下就通过了，那个出现问题的头文件中我使用了std::map，当我把这种容器使用模板代替后，链接就有没事了。（例如：template&lt;class coll&gt;）,后来感到模板技术还有这种效果,赚了!哈哈<br>＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝<br>What are the C and C++ libraries my program would link with?</font> </p> <p><font size="2"><font size="3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Summary Table<br><br></font> <table class="MsoTableGrid" style="border-right: medium none; border-top: medium none; border-left: medium none; border-bottom: medium none; border-collapse: collapse; mso-border-alt: solid windowtext .5pt; mso-yfti-tbllook: 480; mso-padding-alt: 0cm 5.4pt 0cm 5.4pt; mso-border-insideh: .5pt solid windowtext; mso-border-insidev: .5pt solid windowtext" cellspacing="0" cellpadding="0" border="1"> <tbody> <tr style="height: 32pt; mso-yfti-irow: 0"> <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: windowtext 1pt solid; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 1pt solid; width: 426.1pt; padding-top: 0cm; border-bottom: windowtext 1pt solid; height: 32pt; background-color: transparent; mso-border-alt: solid windowtext .5pt" valign="top" width="568"> <p class="MsoNormal" style="margin: 0cm 0cm 0pt"><span lang="EN-US"><span style="mso-spacerun: yes">&nbsp;</span>Compile<span style="mso-spacerun: yes">&nbsp;&nbsp; </span>Old<span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>New IOStream<span style="mso-spacerun: yes">&nbsp;&nbsp; </span><span style="mso-spacerun: yes">&nbsp;</span>Libraries<?xml:namespace prefix = o /><o:p></o:p></span> </p> <p class="MsoNormal" style="margin: 0cm 0cm 0pt"><span lang="EN-US"><span style="mso-spacerun: yes">&nbsp;</span>Option<span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp; </span>IOStream<span style="mso-spacerun: yes">&nbsp;&nbsp; </span><span style="mso-spacerun: yes">&nbsp;</span>or STL<span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>Linked With<o:p></o:p></span> </p></td></tr> <tr style="mso-yfti-irow: 1"> <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 1pt solid; width: 426.1pt; border-top-color: #ece9d8; padding-top: 0cm; border-bottom: windowtext 1pt solid; background-color: transparent; mso-border-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt" valign="top" width="568"> <p class="MsoNormal" style="margin: 0cm 0cm 0pt"><span lang="EN-US"><o:p>&nbsp;</o:p> </span></p></td></tr> <tr style="mso-yfti-irow: 2"> <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 1pt solid; width: 426.1pt; border-top-color: #ece9d8; padding-top: 0cm; border-bottom: windowtext 1pt solid; background-color: transparent; mso-border-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt" valign="top" width="568"> <p class="MsoNormal" style="margin: 0cm 0cm 0pt"><span lang="EN-US"><span style="mso-spacerun: yes">&nbsp;</span>/ML<span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>No<span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>No<span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>LIBC.LIB<o:p></o:p></span> </p></td></tr> <tr style="mso-yfti-irow: 3"> <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 1pt solid; width: 426.1pt; border-top-color: #ece9d8; padding-top: 0cm; border-bottom: windowtext 1pt solid; background-color: transparent; mso-border-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt" valign="top" width="568"> <p class="MsoNormal" style="margin: 0cm 0cm 0pt"><span lang="EN-US"><span style="mso-spacerun: yes">&nbsp;</span>/MLd<span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>No<span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>No<span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>LIBCD.LIB<o:p></o:p></span> </p></td></tr> <tr style="mso-yfti-irow: 4"> <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 1pt solid; width: 426.1pt; border-top-color: #ece9d8; padding-top: 0cm; border-bottom: windowtext 1pt solid; background-color: transparent; mso-border-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt" valign="top" width="568"> <p class="MsoNormal" style="margin: 0cm 0cm 0pt"><span lang="EN-US"><span style="mso-spacerun: yes">&nbsp;</span>/MT<span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>No<span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>No<span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>LIBCMT.LIB<o:p></o:p></span> </p></td></tr> <tr style="mso-yfti-irow: 5"> <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 1pt solid; width: 426.1pt; border-top-color: #ece9d8; padding-top: 0cm; border-bottom: windowtext 1pt solid; background-color: transparent; mso-border-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt" valign="top" width="568"> <p class="MsoNormal" style="margin: 0cm 0cm 0pt"><span lang="EN-US"><span style="mso-spacerun: yes">&nbsp;</span>/MTd<span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>No<span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>No<span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>LIBCMTD.LIB<o:p></o:p></span> </p></td></tr> <tr style="mso-yfti-irow: 6"> <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 1pt solid; width: 426.1pt; border-top-color: #ece9d8; padding-top: 0cm; border-bottom: windowtext 1pt solid; background-color: transparent; mso-border-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt" valign="top" width="568"> <p class="MsoNormal" style="margin: 0cm 0cm 0pt"><span lang="EN-US"><span style="mso-spacerun: yes">&nbsp;</span>/MD<span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>No<span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>No<span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MSVCRT.LIB<o:p></o:p></span> </p></td></tr> <tr style="mso-yfti-irow: 7"> <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 1pt solid; width: 426.1pt; border-top-color: #ece9d8; padding-top: 0cm; border-bottom: windowtext 1pt solid; background-color: transparent; mso-border-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt" valign="top" width="568"> <p class="MsoNormal" style="margin: 0cm 0cm 0pt"><span lang="EN-US"><span style="mso-spacerun: yes">&nbsp;</span>/MDd<span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp; </span>No<span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>No<span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MSVCRTD.LIB<o:p></o:p></span> </p></td></tr> <tr style="mso-yfti-irow: 8"> <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 1pt solid; width: 426.1pt; border-top-color: #ece9d8; padding-top: 0cm; border-bottom: windowtext 1pt solid; background-color: transparent; mso-border-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt" valign="top" width="568"> <p class="MsoNormal" style="margin: 0cm 0cm 0pt"><span lang="EN-US"><span style="mso-spacerun: yes">&nbsp;</span>/ML<span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>No<span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>Yes<span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>LIBC.LIB,<span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span><span style="mso-spacerun: yes">&nbsp;</span>LIBCP.LIB<o:p></o:p></span> </p></td></tr> <tr style="mso-yfti-irow: 9"> <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 1pt solid; width: 426.1pt; border-top-color: #ece9d8; padding-top: 0cm; border-bottom: windowtext 1pt solid; background-color: transparent; mso-border-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt" valign="top" width="568"> <p class="MsoNormal" style="margin: 0cm 0cm 0pt"><span lang="EN-US"><span style="mso-spacerun: yes">&nbsp;</span>/MLd<span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>No<span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Yes<span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>LIBCD.LIB,<span style="mso-spacerun: yes">&nbsp;&nbsp; </span>LIBCPD.LIB<o:p></o:p></span> </p></td></tr> <tr style="mso-yfti-irow: 10"> <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 1pt solid; width: 426.1pt; border-top-color: #ece9d8; padding-top: 0cm; border-bottom: windowtext 1pt solid; background-color: transparent; mso-border-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt" valign="top" width="568"> <p class="MsoNormal" style="margin: 0cm 0cm 0pt"><span lang="EN-US"><span style="mso-spacerun: yes">&nbsp;</span>/MT<span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>No<span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>Yes<span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>LIBCMT.LIB,<span style="mso-spacerun: yes">&nbsp; </span>LIBCPMT.LIB<o:p></o:p></span> </p></td></tr> <tr style="mso-yfti-irow: 11"> <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 1pt solid; width: 426.1pt; border-top-color: #ece9d8; padding-top: 0cm; border-bottom: windowtext 1pt solid; background-color: transparent; mso-border-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt" valign="top" width="568"> <p class="MsoNormal" style="margin: 0cm 0cm 0pt"><span lang="EN-US"><span style="mso-spacerun: yes">&nbsp;</span>/MTd<span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>No<span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Yes<span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="mso-spacerun: yes">&nbsp;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LIBCMTD.LIB, LIBCPMTD.LIB<o:p></o:p></span> </p></td></tr> <tr style="mso-yfti-irow: 12"> <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 1pt solid; width: 426.1pt; border-top-color: #ece9d8; padding-top: 0cm; border-bottom: windowtext 1pt solid; background-color: transparent; mso-border-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt" valign="top" width="568"> <p class="MsoNormal" style="margin: 0cm 0cm 0pt"><span lang="EN-US"><span style="mso-spacerun: yes">&nbsp;</span>/MD<span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>No<span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Yes<span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>MSVCRT.LIB,<span style="mso-spacerun: yes">&nbsp; </span>MSVCPRT.LIB<o:p></o:p></span> </p></td></tr> <tr style="mso-yfti-irow: 13"> <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 1pt solid; width: 426.1pt; border-top-color: #ece9d8; padding-top: 0cm; border-bottom: windowtext 1pt solid; background-color: transparent; mso-border-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt" valign="top" width="568"> <p class="MsoNormal" style="margin: 0cm 0cm 0pt"><span lang="EN-US"><span style="mso-spacerun: yes">&nbsp;</span>/MDd<span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>No<span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>Yes<span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>MSVCRTD.LIB, MSVCPRTD.LIB<o:p></o:p></span> </p></td></tr> <tr style="mso-yfti-irow: 14"> <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 1pt solid; width: 426.1pt; border-top-color: #ece9d8; padding-top: 0cm; border-bottom: windowtext 1pt solid; background-color: transparent; mso-border-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt" valign="top" width="568"> <p class="MsoNormal" style="margin: 0cm 0cm 0pt"><span lang="EN-US"><span style="mso-spacerun: yes">&nbsp;</span>/ML<span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>Yes<span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>No<span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>LIBC.LIB,<span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span><span style="mso-spacerun: yes">&nbsp; </span>LIBCI.LIB<o:p></o:p></span> </p></td></tr> <tr style="mso-yfti-irow: 15"> <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 1pt solid; width: 426.1pt; border-top-color: #ece9d8; padding-top: 0cm; border-bottom: windowtext 1pt solid; background-color: transparent; mso-border-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt" valign="top" width="568"> <p class="MsoNormal" style="margin: 0cm 0cm 0pt"><span lang="EN-US"><span style="mso-spacerun: yes">&nbsp;</span>/MLd<span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>Yes<span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>No<span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>LIBCD.LIB,<span style="mso-spacerun: yes">&nbsp;&nbsp; </span><span style="mso-spacerun: yes">&nbsp;</span>LIBCID.LIB<o:p></o:p></span> </p></td></tr> <tr style="mso-yfti-irow: 16"> <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 1pt solid; width: 426.1pt; border-top-color: #ece9d8; padding-top: 0cm; border-bottom: windowtext 1pt solid; background-color: transparent; mso-border-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt" valign="top" width="568"> <p class="MsoNormal" style="margin: 0cm 0cm 0pt"><span lang="EN-US"><span style="mso-spacerun: yes">&nbsp;</span>/MT<span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>Yes<span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>No<span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LIBCMT.LIB,<span style="mso-spacerun: yes">&nbsp; </span><span style="mso-spacerun: yes">&nbsp;</span>LIBCIMT.LIB<o:p></o:p></span> </p></td></tr> <tr style="mso-yfti-irow: 17"> <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 1pt solid; width: 426.1pt; border-top-color: #ece9d8; padding-top: 0cm; border-bottom: windowtext 1pt solid; background-color: transparent; mso-border-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt" valign="top" width="568"> <p class="MsoNormal" style="margin: 0cm 0cm 0pt"><span lang="EN-US"><span style="mso-spacerun: yes">&nbsp;</span>/MTd<span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>Yes<span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>No<span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LIBCMTD.LIB, <span style="mso-spacerun: yes">&nbsp;</span>LIBCIMTD.LIB<o:p></o:p></span> </p></td></tr> <tr style="mso-yfti-irow: 18"> <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 1pt solid; width: 426.1pt; border-top-color: #ece9d8; padding-top: 0cm; border-bottom: windowtext 1pt solid; background-color: transparent; mso-border-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt" valign="top" width="568"> <p class="MsoNormal" style="margin: 0cm 0cm 0pt"><span lang="EN-US"><span style="mso-spacerun: yes">&nbsp;</span>/MD<span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>Yes<span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>No<span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MSVCRT.LIB,<span style="mso-spacerun: yes">&nbsp; </span>MSVCIRT.LIB<o:p></o:p></span> </p></td></tr> <tr style="mso-yfti-irow: 19; mso-yfti-lastrow: yes"> <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 1pt solid; width: 426.1pt; border-top-color: #ece9d8; padding-top: 0cm; border-bottom: windowtext 1pt solid; background-color: transparent; mso-border-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt" valign="top" width="568"> <p class="MsoNormal" style="margin: 0cm 0cm 0pt"><span lang="EN-US"><span style="mso-spacerun: yes">&nbsp;</span>/MDd<span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>Yes<span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>No<span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>MSVCRTD.LIB, MSVCIRTD.LIB<o:p></o:p></span> </p></td></tr></tbody></table><br></font></p> <p><font size="2">你的程序使用了/ML编译选项,而程序依赖的.lib可能使用/MDd选项编译,造成链接冲突.</font> </p> <p><font size="2">统一编译选项可回避此错误<br>Project Settings-&gt;C/C++ Tab-&gt;Category:CodeGeneration<br>Use run-time library组合框中选择Multithread Dll(或Debug Multithread Dll )</font> <br></p> <p><font size="2"><font color="#008000" size="3">Summary Table for CRT DLLs Used<br></font> <table class="table" cellspacing="1"> <tbody> <tr> <td>Import Library Linked With </td> <td>DLLs Used (Visual C++ 5.0|6.0) </td> <td>DLLs Used (Visual C++ 4.2)</td> <td>DLLs Used (Visual C++ .NET 2002| Visual C++ .NET 2003)</td></tr> <tr> <td>MSVCRT.LIB </td> <td>MSVCRT.DLL </td> <td>MSVCRT.DLL </td> <td>MSVCRT.DLL </td></tr> <tr> <td>MSVCRTD.LIB </td> <td>MSVCRTD.DLL</td> <td>MSVCRTD.DLL </td> <td>MSVCRTD.DLL</td></tr> <tr> <td>MSVCPRT.LIB </td> <td>MSVCP(5|6)0.DLL</td> <td>&nbsp;</td> <td>MSVCP7(0|1).DLL </td></tr> <tr> <td>MSVCPRTD.LIB </td> <td>MSVCP(5|6)0D.DLL </td> <td>&nbsp;</td> <td>MSVCP7(0|1)D.DLL </td></tr> <tr> <td>MSVCIRT.LIB </td> <td>MSVCIRT.DLL </td> <td>MSVCIRT.DLL</td> <td>&nbsp;</td></tr> <tr> <td>MSVCIRTD.LIB</td> <td>MSVCIRTD.DLL </td> <td>MSVCIRTD.DLL</td> <td>&nbsp;</td></tr></tbody></table><br><br>注意：所有相关工程都应该选择相同编译选项<br>＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝<br>微软的MSDN中查到信息的</font> </p> <p><font size="2">可能的原因</font> </p> <p><font size="2">不慎同时与单线程库和多线程库链接。确保应用程序项目文件只包括适当的库，并且任何第三方库已适当创建了单线程或多线程版本。<br>该符号为封装函数（通过用 /Gy 编译创建），包含在多个文件中，但在各编译间已改变。重新编译所有包含 symbol 的文件。<br>以不同的形式在不同库中的两个成员对象中定义了该符号，并且使用了这两个成员对象。<br>某个绝对符号被定义两次，而每次定义的值不同。<br>头文件声明并定义了变量。可能的解决方案有：<br>在 .h 中声明变量：extern BOOL MyBool;，然后在 .c 或 .cpp 文件中向它分配：BOOL MyBool = FALSE;。<br>将变量声明为 Static。<br>将变量声明为 selectany。<br>当将 uuid.lib 与定义 GUID 的其他 .lib 文件（例如 oledb.lib 和 adsiid.lib）一起使用时。例如：<br>oledb.lib(oledb_i.obj) : error LNK2005: _IID_ITransactionObject<br>already defined in uuid.lib(go7.obj)<br>若要修复，请将 /FORCE:MULTIPLE 添加到链接器命令行选项，并确保 uuid.lib 是引用的第一个库。</font> </p> <p><font size="2">有关更多信息，请参阅知识库文章：</font> </p> <p><font size="2">Q148652，PRB: LNK2005 Errors When Link C Run-Time Libraries Are Linked Before MFC Libraries。<br>Q140440，FIX: Global Overloaded Delete Operator Causes LNK2005。<br>Q184235，PRB: LNK2005 Errors on New and Delete When Defining _ATL_MIN_CRT。<br>该错误之后为致命错误 LNK1169。<br>＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝<br>有时候因为工程使用了预编译头文件并且是增量编译，所以当你改动以后可能也会出现LNK2005错误，提示“XXXX已经在XXXX.obj文件中定义”的消息，这时候只要Rebuild All一般都能解决问题。这是因为头文件的顺序被改动等等操作造成的。<br>最后要说明的：事物是在不断变化中的，C++的标准在变化，编译器也在变化，所以并不是所有的LNK2005错误都可以在这里找到答案，但是至少它能给你以提示。学习并思考才是正确的！</font> </p></div></div></form><img src ="http://www.cppblog.com/woaidongmao/aggbug/67070.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/woaidongmao/" target="_blank">肥仔</a> 2008-11-16 20:57 <a href="http://www.cppblog.com/woaidongmao/archive/2008/11/16/67070.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>头文件定义的函数，加Inline，否则容易出现link 2005错误</title><link>http://www.cppblog.com/woaidongmao/archive/2008/11/15/67009.html</link><dc:creator>肥仔</dc:creator><author>肥仔</author><pubDate>Sat, 15 Nov 2008 10:35:00 GMT</pubDate><guid>http://www.cppblog.com/woaidongmao/archive/2008/11/15/67009.html</guid><wfw:comment>http://www.cppblog.com/woaidongmao/comments/67009.html</wfw:comment><comments>http://www.cppblog.com/woaidongmao/archive/2008/11/15/67009.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/woaidongmao/comments/commentRss/67009.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/woaidongmao/services/trackbacks/67009.html</trackback:ping><description><![CDATA[<p>.h中文件定义的函数默认为inline，但有时候却不是如此，所以加上inline，可避免出现link 2005 错误。因为多个cpp包含这个.h的话，函数定义会出现在多个.obj中。、</p> <p>&nbsp;</p> <p>&nbsp;</p> <p>&nbsp;</p> <p><var></var>我写了一个函数放到了一个abc.h文件中，在mfc项目的stdafx.h中添加了包含abc.h&nbsp;&nbsp; ,则&nbsp;&nbsp; 出现链接错误LNK2005 <br>如不放到stdafx.h中，而直接在使用这个函数的cpp文件里包含这个abc.h&nbsp;&nbsp; 就不会有错 <var>20</var> 回复次数：<var>8</var> <p>第1个回答<br>你这个abc.h有函数实现么? <br>有没有定义全局变量?  <hr>  <p>第2个回答<br>谢谢帮助，abc.h <br>中有函数实现，但没有全局变量  <hr>  <p>第3个回答<br>#ifndef&nbsp;&nbsp; _ABCFUNC <br>#define&nbsp;&nbsp; _ABCFUNC <br>在此处添加函数定义 <br>#endif  <hr>  <p>第4个回答<br>使用inline.  <hr>  <p>第5个回答<br>#ifndef&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _ABCFUNC <br>#define&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _ABCFUNC <br>在此处添加函数定义 <br>#endif <br>已经加上了&nbsp;&nbsp; 用的是&nbsp;&nbsp; #pragma&nbsp;&nbsp; once&nbsp;&nbsp; <br>加入&nbsp;&nbsp; 使用inline.&nbsp;&nbsp; 确实解决了问题&nbsp;&nbsp; 还请&nbsp;&nbsp; xyzhaopeng&nbsp;&nbsp;&nbsp;&nbsp; 讲讲为什么&nbsp;&nbsp; <hr>  <p>第6个回答<br>编译器认为你对函数没有作声明，所以会&nbsp;&nbsp; 出错，加上inline就说明你的函数是个内联函数，这样编译器就会认为你是在声明时加的函数体。  <hr>  <p>第7个回答<br>编译器是编译每个cpp文件,你在abc.h里面写了函数的实现,afx.h里面include了abc.h, <br>而有很多gecpp文件include了afx.h,也就是很多个cpp文件里面有这个函数的实现, <br>在链接器链接时就会发现有多个同名函数,所以会报错. <br>如果最终只有一个cpp文件include了abc.h则不会出错,或者在abc.h中将函数申明为inline.  <hr>  <p>第8个回答<br>谢谢各位的热心帮助&nbsp;&nbsp; <br>我是在学习wtl <br>wtl没有cpp文件，所有实现都写在了h文件里面 <br>却没有这种问题呢？  <p>&nbsp;</p> <p>&nbsp;</p> <p>#####################################################################################################</p> <p>#####################################################################################################</p> <p><br><a name="3796167173"></a>VC的LNK2005错误，用于避免重复包含的宏为什么无效？ </p> <p>头文件设置如下： <br>#ifndef _MY_HPP_ <br>#define _MY_HPP_ <br>/* <br>内容： <br>函数A <br>函数B <br>…… <br>*/ <br>#endif <br>可当我在同一工程的多个cpp文件（例如文件1和文件2）里#include此头文件时，编译倒能正常通过，可是连接时却出现了报错。大致意思是说：“在文件1.obj中的函数A已经在文件2中定义。”而且是头文件中有多少个函数就会出现多少条这样的连接错误提示。 <br>既然已经设置了保护宏，为什么还不管用呢？急问，拜托了，叩谢。 <p>作者： 125.33.0.* <p>2008-5-6 20:08 <a href="http://tieba.baidu.com/#sub">回复此发言</a> <hr align="left" width="87%" size="1">  <p><a name="#2"></a> <p>2<br><a name="3796538578"></a>回复：VC的LNK2005错误，用于避免重复包含的宏为什么无效？  <p>如果把被提示的函数设置为inline就不会报错了，可我总不能把所有函数都声明成inline吧？该怎么办啊？ <p>作者： 125.33.0.* <p>2008-5-6 20:54 <a href="http://tieba.baidu.com/#sub">回复此发言</a> <hr align="left" width="87%" size="1">  <p><a name="#3"></a> <p>3<br><a name="3797615124"></a>回复：VC的LNK2005错误，用于避免重复包含的宏为什么无效？  <p>"如果把被提示的函数设置为inline就不会报错了" <br>说明你在头文件里面有实现。。 <br>这样多个包含这个头文件的cpp文件都有实现 <br>link的时候就有多分。 <br>头文件一般是申明， 实现应该放到某一个cpp文件里面 <br>这样link的时候就只有一份在“某一个cpp文件” <p>作者： 125.34.177.* <p>2008-5-6 23:14 <a href="http://tieba.baidu.com/#sub">回复此发言</a> <hr align="left" width="87%" size="1">  <p><a name="#4"></a> <p>4<br><a name="3797972669"></a>回复：VC的LNK2005错误，用于避免重复包含的宏为什么无效？  <p>终于有回复了，感激涕零ing……T_T <br>Sorry……我那个头文件说穿了就是个为了以后公用而写的“函数库”，是独立于当前工程之外的，故而头文件里的这些函数也不是任何一个类的成员函数。 <br>况且，这个头文件在Dev-Cpp里即使包含了多次也没有任何错误的啊。 <br>还有，如果真的要把这些函数的实现挪到cpp里，那岂不还是得把这个cpp文件同样在包含此头文件的位置上照旧#include一遍，跟直接#include这个头文件还有什么不同呢？ <br>OK，不管怎么着，先谢谢3楼的老大了：） <p>作者： 125.33.10.* <p>2008-5-7 00:18 <a href="http://tieba.baidu.com/#sub">回复此发言</a> <hr align="left" width="87%" size="1">  <p><a name="#5"></a> <p>5<br><a name="3798158429"></a>回复：VC的LNK2005错误，用于避免重复包含的宏为什么无效？  <p>晕 <br>是这样写 <br>common.h 当中声明 <br>如 <br>#ifudef <br>.... <br>void foo(); <br>#endif <br>common.cpp 当中写实现 <br>#include"common.h" <br>void foo() <br>{ <br>.... <br>} <br>然后调用的文件只需要包含头文件就行了 <br>#include"common" <br>int call() <br>{ <br>foo(); <br>} <br>include的意思就是把整个文件的类容copy过来。 <p>作者： <a href="http://passport.baidu.com/?detail&amp;aid=6&amp;default_tab=1&amp;un=%C7%F3%CA%C7%B5%C4%C3%CE">求是的梦</a> <p><a href="http://hi.baidu.com/zjugator"><img src="http://img.baidu.com/passport/space_open.gif" align="absMiddle" border="0"></a> <p><img src="http://tieba.baidu.com/tb/img/hi/hiOffline.gif" align="absBottom" border="0"> <p>2008-5-7 01:05 <a href="http://tieba.baidu.com/#sub">回复此发言</a> <hr align="left" width="87%" size="1">  <p><a name="#6"></a> <p>6<br><a name="3798251828"></a>回复：VC的LNK2005错误，用于避免重复包含的宏为什么无效？  <p>刚刚在Dev-Cpp里试了一下3、5楼的双文件法，结果成功通过了连接，待会去VC里试试看-_- <br>可是……可是话说回来，难道写有函数定义的头文件就真的“永远”不能在同一个工程中的不同文件里重复#include了吗？都需要另建一个c或cpp文件来做写函数定义体才能连接成功的吗？ <br>——该不会我这么久以来所坚信的“在头文件里设置了重复包含保护宏之后就可以随意#include了”的观点一直就是错的吧？天！无论如何，先谢谢二位提点，我这就去测验一遍看看…… <p>作者： 125.33.10.* <p>2008-5-7 01:34 <a href="http://tieba.baidu.com/#sub">回复此发言</a> <hr align="left" width="87%" size="1">  <p><a name="#7"></a> <p>7<br><a name="3803617772"></a>回复：VC的LNK2005错误，用于避免重复包含的宏为什么无效？  <p>还是不对呀，按照5楼的方式编写2个文件： <br>//头文件 <br>#ifndef MY_H <br>#define MY_H <br>/* <br>函数声明…… <br>*/ <br>#endif <br>//实现文件 <br>#include &lt;同名头文件&gt; <br>/* <br>函数定义…… <br>*/ <br>连接时LNK2005倒是消失了，可又出现了新的错误： <br>error LNK2001: unresolved symbol "函数A"(...) <br>error LNK2001: unresolved symbol "函数B"(...) <br>…… <br>俨然一副“当前工程中找不到函数定义”的样子，可我如果把实现文件针对添加到工程里的话，跟我的最初“只#include头文件、不增加工程文件数”的期望可就完全背道而驰了啊。 <br>★★★★★★★★★★ <br>简而言之：怎么才能使我的头文件像自带的头文件（如&lt;iostream&gt;、&lt;string&gt;或&lt;stdio.h&gt;）一样可以随处#include呢？ <br>★★★★★★★★★★ <p>作者： 125.33.19.* <p>2008-5-7 20:06 <a href="http://tieba.baidu.com/#sub">回复此发言</a> <hr align="left" width="87%" size="1">  <p><a name="#8"></a> <p>8<br><a name="3805573172"></a>回复：VC的LNK2005错误，用于避免重复包含的宏为什么无效？  <p>大家一般是怎么写这种dú-lì的通用式头文件的呢？ <br>只用同一个头文件来同时包含函数的声明和定义、并在同一工程中多次#include，究竟可不可行？能不能实现呢？ <p>作者： 125.33.1.* <p>2008-5-8 00:35 <a href="http://tieba.baidu.com/#sub">回复此发言</a> <hr align="left" width="87%" size="1">  <p><a name="#9"></a> <p>9<br><a name="3813438038"></a>或者说是暂时解决  <p>呼~非得把所有函数都设置为static之后才能随处#include……-_- <p>作者： <a href="http://passport.baidu.com/?detail&amp;aid=6&amp;default_tab=1&amp;un=%CE%CA%CC%E2%BD%E2%BE%F6%C0%B2">问题解决啦</a> <p><img src="http://tieba.baidu.com/tb/img/hi/hiOffline.gif" align="absBottom" border="0"> <p>2008-5-9 03:14 <a href="http://tieba.baidu.com/#sub">回复此发言</a></p><img src ="http://www.cppblog.com/woaidongmao/aggbug/67009.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/woaidongmao/" target="_blank">肥仔</a> 2008-11-15 18:35 <a href="http://www.cppblog.com/woaidongmao/archive/2008/11/15/67009.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>有点意思struct代码设计</title><link>http://www.cppblog.com/woaidongmao/archive/2008/11/11/66580.html</link><dc:creator>肥仔</dc:creator><author>肥仔</author><pubDate>Tue, 11 Nov 2008 02:21:00 GMT</pubDate><guid>http://www.cppblog.com/woaidongmao/archive/2008/11/11/66580.html</guid><wfw:comment>http://www.cppblog.com/woaidongmao/comments/66580.html</wfw:comment><comments>http://www.cppblog.com/woaidongmao/archive/2008/11/11/66580.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/woaidongmao/comments/commentRss/66580.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/woaidongmao/services/trackbacks/66580.html</trackback:ping><description><![CDATA[<p>用数组＋指针＋半面向对象（C）或 集合＋指针＋CLASS（C++）。<br>具体可以参考GTK+的代码，这里举一个简单的例子：  <p>#include &lt;stdio.h&gt;<br>#include &lt;stdlib.h&gt;<br>enum{<br>&nbsp;&nbsp;&nbsp; STRUCT_S1,<br>&nbsp;&nbsp;&nbsp; STRUCT_S2<br>};<br>struct base{<br>&nbsp;&nbsp;&nbsp; const int type;<br>};<br>struct s1{<br>&nbsp;&nbsp;&nbsp; const int type;//必须位于第一个。<br>&nbsp;&nbsp;&nbsp; int abc;<br>&nbsp;&nbsp;&nbsp; int def;<br>};<br>struct s2{<br>&nbsp;&nbsp;&nbsp; const int type;//必须位于第一个。<br>&nbsp;&nbsp;&nbsp; long jsk;<br>&nbsp;&nbsp;&nbsp; char abcde[10];<br>};<br>int main()<br>{<br>&nbsp;&nbsp;&nbsp; void * a[10]={0};<br>&nbsp;&nbsp;&nbsp; struct s1 b={STRUCT_S1, 1, 2};<br>&nbsp;&nbsp;&nbsp; struct s2 c={STRUCT_S2, 111, "123"};<br>&nbsp;&nbsp;&nbsp; a[0] = &amp;b;<br>&nbsp;&nbsp;&nbsp; a[1] = &amp;c;<br>&nbsp;&nbsp;&nbsp; int i;<br>&nbsp;&nbsp;&nbsp; for(i=0; i&lt;10; i++)<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct base * base;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(base = a[i])<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; switch(base-&gt;type){<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case STRUCT_S1:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct s1 *p = a[i];<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("%d %d\n", p-&gt;abc, p-&gt;def);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case STRUCT_S2:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct s2 *p = a[i];<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("%ld %s\n", p-&gt;jsk, p-&gt;abcde);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; return 0;<br>}</p><img src ="http://www.cppblog.com/woaidongmao/aggbug/66580.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/woaidongmao/" target="_blank">肥仔</a> 2008-11-11 10:21 <a href="http://www.cppblog.com/woaidongmao/archive/2008/11/11/66580.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>成员函数指针与高性能的C++委托（Fastest Possible C++ Delegates）</title><link>http://www.cppblog.com/woaidongmao/archive/2008/11/09/66438.html</link><dc:creator>肥仔</dc:creator><author>肥仔</author><pubDate>Sun, 09 Nov 2008 10:53:00 GMT</pubDate><guid>http://www.cppblog.com/woaidongmao/archive/2008/11/09/66438.html</guid><wfw:comment>http://www.cppblog.com/woaidongmao/comments/66438.html</wfw:comment><comments>http://www.cppblog.com/woaidongmao/archive/2008/11/09/66438.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/woaidongmao/comments/commentRss/66438.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/woaidongmao/services/trackbacks/66438.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: Member Function Pointers and the Fastest Possible C++ Delegates &nbsp; 引子 标准C++中没有真正的面向对象的函数指针。这一点对C++来说是不幸的，因为面向对象的指针（也叫做“闭包（closure）”或“委托（delegate）”）在一些语言中已经证明了它宝贵的价值。在Delphi (Object Pascal)中，面向对象的函...&nbsp;&nbsp;<a href='http://www.cppblog.com/woaidongmao/archive/2008/11/09/66438.html'>阅读全文</a><img src ="http://www.cppblog.com/woaidongmao/aggbug/66438.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/woaidongmao/" target="_blank">肥仔</a> 2008-11-09 18:53 <a href="http://www.cppblog.com/woaidongmao/archive/2008/11/09/66438.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>把C++类成员方法直接作为线程回调函数</title><link>http://www.cppblog.com/woaidongmao/archive/2008/11/09/66435.html</link><dc:creator>肥仔</dc:creator><author>肥仔</author><pubDate>Sun, 09 Nov 2008 10:42:00 GMT</pubDate><guid>http://www.cppblog.com/woaidongmao/archive/2008/11/09/66435.html</guid><wfw:comment>http://www.cppblog.com/woaidongmao/comments/66435.html</wfw:comment><comments>http://www.cppblog.com/woaidongmao/archive/2008/11/09/66435.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/woaidongmao/comments/commentRss/66435.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/woaidongmao/services/trackbacks/66435.html</trackback:ping><description><![CDATA[<p></p> <p class="MsoNormal" style="background: white; margin: 0cm 6pt 6pt; word-break: break-all; text-indent: 24pt; line-height: 16.5pt; text-align: left; mso-pagination: widow-orphan" align="left"><span style="font-size: 12pt; color: black; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">我以前写线程时要么老老实实照着声明写<span lang="EN-US">,</span>要么使用<span lang="EN-US">C++</span>类的静态成员函数来作为回调函数<span lang="EN-US">,</span>经常会因为线程代码而破坏封装<span lang="EN-US">.</span>之前虽然知道类成员函数的展开形式，但从没想过利用过它，昨天看深入<span lang="EN-US">ATL</span>时无意中学会了这一招<span lang="EN-US">:) <?xml:namespace prefix = o /><o:p></o:p></span></span></p> <p class="MsoNormal" style="background: white; margin: 12pt 6pt 6pt; word-break: break-all; text-indent: 24pt; line-height: 16.5pt; text-align: left; mso-pagination: widow-orphan" align="left"><span style="font-size: 12pt; color: black; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">类成员方法是一个比较特殊的函数，它在编译时会被转化成普通函数，比如有<span lang="EN-US">TMyClass</span>类<span lang="EN-US">:<br>class TMyClass{<br>&nbsp;&nbsp;&nbsp; void Func();<br>};<o:p></o:p></span></span></p> <p class="MsoNormal" style="background: white; margin: 12pt 6pt 6pt; word-break: break-all; text-indent: 24pt; line-height: 16.5pt; text-align: left; mso-pagination: widow-orphan" align="left"><span style="font-size: 12pt; color: black; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">这个<span lang="EN-US">TMyClass::Func</span>最终会转化成<span lang="EN-US"> void Func(TMyClass *this); </span>也就是说在原第一个参数前插入指向对象本身的<span lang="EN-US">this</span>指针。<span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal" style="background: white; margin: 12pt 6pt 6pt; word-break: break-all; text-indent: 24pt; line-height: 16.5pt; text-align: left; mso-pagination: widow-orphan" align="left"><span style="font-size: 12pt; color: black; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">我们可以利用这个特性写一个非静态类成员方法来直接作为线程回调函数，先看<span lang="EN-US">_beginthread</span>函数的定义<span lang="EN-US">:<br>unsigned long _RTLENTRY _EXPFUNC _beginthread (void (_USERENTRY *__start)(void *),unsigned __stksize, void *__arg);<br></span>其中的第一个参数就是作为线程执行主体的回调函数。它的原型是<span lang="EN-US">:void Func(void *)</span>，这个<span lang="EN-US">void*</span>参数是作为自定义数据传入的。对比一下上面所说的<span lang="EN-US">TMyClass::Func</span>的最终形式，它正好可以符合这里的要求。<span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal" style="background: white; margin: 12pt 6pt 6pt; word-break: break-all; text-indent: 24pt; line-height: 16.5pt; text-align: left; mso-pagination: widow-orphan" align="left"><span style="font-size: 12pt; color: black; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">现在做个实验<span lang="EN-US">:<br>#include &lt;stdio.h&gt;<br>#include &lt;process.h&gt;<o:p></o:p></span></span></p> <p class="MsoNormal" style="background: white; margin: 12pt 6pt 6pt; word-break: break-all; text-indent: 24pt; line-height: 16.5pt; text-align: left; mso-pagination: widow-orphan" align="left"><span lang="EN-US" style="font-size: 12pt; color: black; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">class TMyClass{<br>&nbsp;&nbsp;&nbsp; int m_nCount;<br>&nbsp;&nbsp;&nbsp; int m_nId;<br>public:<br>&nbsp;&nbsp;&nbsp; TMyClass(int nId,int nCount)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; :m_nId(nId),m_nCount(nCount)<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp; }<o:p></o:p></span></p> <p class="MsoNormal" style="background: white; margin: 12pt 6pt 6pt; word-break: break-all; text-indent: 24pt; line-height: 16.5pt; text-align: left; mso-pagination: widow-orphan" align="left"><span lang="EN-US" style="font-size: 12pt; color: black; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">&nbsp;&nbsp;&nbsp; void _USERENTRY ThreadProc()&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // </span><span style="font-size: 12pt; color: black; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">类成员方法<span lang="EN-US"><br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for(int i=0; i&lt;m_nCount; i++)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // </span>根据<span lang="EN-US">m_nCount</span>成员打印一排数字<span lang="EN-US"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("Class%d : %d\n",m_nId,i);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; }<br>};<o:p></o:p></span></span></p> <p class="MsoNormal" style="background: white; margin: 12pt 6pt 6pt; word-break: break-all; text-indent: 24pt; line-height: 16.5pt; text-align: left; mso-pagination: widow-orphan" align="left"><span lang="EN-US" style="font-size: 12pt; color: black; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">int main(int argc, char* argv[])<br>{<br>&nbsp;&nbsp;&nbsp; </span><span lang="EN-US" style="font-size: 12pt; color: red; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">union {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // </span><span style="font-size: 12pt; color: red; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">联合类，用于转换类成员方法指针到普通函数指针（试过编译器不允许在这两种函数之间强制转换），不知道有没有更好的方法。<span lang="EN-US"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; void (_USERENTRY *ThreadProc)(void *);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; void (_USERENTRY TMyClass::*MemberProc)();<br>&nbsp;&nbsp;&nbsp; } Proc;&nbsp;&nbsp; </span></span><span lang="EN-US" style="font-size: 12pt; color: black; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // </span><span style="font-size: 12pt; color: black; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">尽管联合里的两种函数类型现在看起来有很大不同，但它们的最终形式是相同的。<span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal" style="background: white; margin: 12pt 6pt 6pt; word-break: break-all; text-indent: 24pt; line-height: 16.5pt; text-align: left; mso-pagination: widow-orphan" align="left"><span lang="EN-US" style="font-size: 12pt; color: black; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">&nbsp;&nbsp;&nbsp; TMyClass MyClass1(1,10),MyClass2(2,5); // </span><span style="font-size: 12pt; color: black; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">产生两个<span lang="EN-US">TMyClass</span>对象<span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal" style="background: white; margin: 12pt 6pt 6pt; word-break: break-all; text-indent: 24pt; line-height: 16.5pt; text-align: left; mso-pagination: widow-orphan" align="left"><span lang="EN-US" style="font-size: 12pt; color: black; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">&nbsp;&nbsp;&nbsp; Proc.MemberProc = &amp;TMyClass::ThreadProc;&nbsp;&nbsp; // </span><span style="font-size: 12pt; color: black; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">转换，<span lang="EN-US">Proc.ThreadProc</span>就是对应的普通函数指针了<span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal" style="background: white; margin: 12pt 6pt 6pt; word-break: break-all; text-indent: 24pt; line-height: 16.5pt; text-align: left; mso-pagination: widow-orphan" align="left"><span lang="EN-US" style="font-size: 12pt; color: black; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">&nbsp;&nbsp;&nbsp; _beginthread(Proc.ThreadProc,4096,&amp;MyClass1);&nbsp;&nbsp; // </span><span style="font-size: 12pt; color: black; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">开始线程，这里的<span lang="EN-US">Proc.ThreadProc</span>实际上是<span lang="EN-US">TMyClass::ThreadProc, </span>它要的<span lang="EN-US">this</span>指针是我们给的<span lang="EN-US">&amp;MyClass1</span>。<span lang="EN-US"><br>&nbsp;&nbsp;&nbsp; _beginthread(Proc.ThreadProc,4096,&amp;MyClass2);<br>&nbsp;&nbsp;&nbsp; system("pause");<br>&nbsp;&nbsp;&nbsp; return 0;<br>}<o:p></o:p></span></span></p> <p class="MsoNormal" style="background: white; margin: 12pt 6pt 6pt; word-break: break-all; text-indent: 24pt; line-height: 16.5pt; text-align: left; mso-pagination: widow-orphan" align="left"><span style="font-size: 12pt; color: black; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">运行！神奇吧？<span lang="EN-US">:-)<o:p></o:p></span></span></p> <p class="MsoNormal" style="background: white; margin: 12pt 6pt 0pt; word-break: break-all; text-indent: 24pt; line-height: 16.5pt; text-align: left; mso-pagination: widow-orphan" align="left"><span style="font-size: 12pt; color: black; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">其实不止线程回调函数，其实只要是形如<span lang="EN-US">Func(void*,...)</span>的回调函数都可以用这种方法直接使用类成员方法。<span lang="EN-US">(</span>前提是第一个<span lang="EN-US">void*</span>是自定义数据，也就是说它不能有其它功能<span lang="EN-US">)</span>。<span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal"><span lang="EN-US" style="font-size: 12pt; color: black; font-family: 宋体; mso-bidi-font-family: arial"><o:p>&nbsp;</o:p></span></p><img src ="http://www.cppblog.com/woaidongmao/aggbug/66435.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/woaidongmao/" target="_blank">肥仔</a> 2008-11-09 18:42 <a href="http://www.cppblog.com/woaidongmao/archive/2008/11/09/66435.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>模版函数指针，C++委托的实现</title><link>http://www.cppblog.com/woaidongmao/archive/2008/11/09/66434.html</link><dc:creator>肥仔</dc:creator><author>肥仔</author><pubDate>Sun, 09 Nov 2008 10:39:00 GMT</pubDate><guid>http://www.cppblog.com/woaidongmao/archive/2008/11/09/66434.html</guid><wfw:comment>http://www.cppblog.com/woaidongmao/comments/66434.html</wfw:comment><comments>http://www.cppblog.com/woaidongmao/archive/2008/11/09/66434.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/woaidongmao/comments/commentRss/66434.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/woaidongmao/services/trackbacks/66434.html</trackback:ping><description><![CDATA[<p style="line-height: 150%"><span style="color: black; mso-bidi-font-family: arial">今天写引擎的时候，很想加入一些回调函数，以前一直没时间整理这块，这次一定要下决心好好整整代码，纯粹用多态，很多类非要加个帽子，类之间的关系也显的很单一，有的情况需要用到委托的回调机制，这是个很好的东西，在<span lang="EN-US">C#</span>里面是原生支持的，<span lang="EN-US">C++</span>里面本来函数指针是个不错的选择，可到了对象里面，成员函数指针还有那么好用吗？这原本是另<span lang="EN-US">C++</span>程序员非常失望和无赖的，难道一说到成员函数指针就真的那么不好用，甚至要沦为被唾弃的命运？并非入此，别忘了，<span lang="EN-US">C++</span>里面还有很强的利器，<span lang="EN-US">C#</span>和<span lang="EN-US">Java</span>后天才具备的特性可是<span lang="EN-US">C++</span>先天就具备的哦，那就是范型，<span lang="EN-US">C++</span>里面的用的是模版，而且如果把 模版和成员函数指针结合在一起，那就威力无比了，那应该叫做就是<span lang="EN-US">“</span>成员模版函数指针<span lang="EN-US">”</span>，<span lang="EN-US">C++</span>的教科书上有这个名词吗？我查了查，好像是没有，而且网上很多资料竟然说这个不能实现之类的话，我都怀疑那些如此断言的人是否太不负责仁了，误导人啊。<span lang="EN-US"><?xml:namespace prefix = o /><o:p></o:p></span></span></p> <p style="line-height: 150%"><span style="color: black; mso-bidi-font-family: arial">当然指想成员函数的指针，这里面的确有段<span lang="EN-US">C++</span>设计的问题，<span lang="EN-US">C++</span>的成员函数地址通过对象外去引用不能直接通过<span lang="EN-US">“&amp;</span>对象<span lang="EN-US">.</span>方法<span lang="EN-US">”</span>的方式来引用，这个在<span lang="EN-US">C++</span>标准里面是没有的，很多人到这里就绝望了，可间接引用呢？而且用很优雅的方式来引用呢？<span lang="EN-US"><o:p></o:p></span></span></p> <p style="line-height: 150%"><span style="color: black; mso-bidi-font-family: arial">好了，我也不绕圈子了，给出我的代码，一个简单的<span lang="EN-US"> “</span>成员模版函数指针<span lang="EN-US">” </span>的实现，看看<span lang="EN-US">C++</span>是如何优雅的实现委托的，真的非常非常的优雅，由于完全自己摸索出来的，真是感慨万千啊。<span lang="EN-US"><o:p></o:p></span></span></p> <p style="line-height: 150%"><span lang="EN-US" style="color: black; mso-bidi-font-family: arial">#include "stdafx.h"<o:p></o:p></span></p> <p style="line-height: 150%"><span lang="EN-US" style="color: black; mso-bidi-font-family: arial">#include &lt;iostream&gt;<o:p></o:p></span></p> <p style="line-height: 150%"><span lang="EN-US" style="color: black; mso-bidi-font-family: arial">using namespace std;<o:p></o:p></span></p> <p style="line-height: 150%"><span lang="EN-US" style="color: black; mso-bidi-font-family: arial">template&lt;typename T&gt;<br>class A<br>{<br>private:<br>&nbsp;&nbsp; typedef int (T::*delegateFun)(int);<br>&nbsp;&nbsp; T * _This;<br>&nbsp;&nbsp; delegateFun _deleGate;<o:p></o:p></span></p> <p style="line-height: 150%"><span lang="EN-US" style="color: black; mso-bidi-font-family: arial">public:&nbsp;&nbsp;&nbsp; <o:p></o:p></span></p> <p style="line-height: 150%"><span lang="EN-US" style="color: black; mso-bidi-font-family: arial"> //This</span><span style="color: black; mso-bidi-font-family: arial">被代理的对象<span lang="EN-US">, delegateFun</span>被代理的方法<span lang="EN-US"><br>&nbsp;<br> A(T * This, int (T::*delegateFun)(int))<br> { <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _This = This;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _deleGate = delegateFun;<br> }<o:p></o:p></span></span></p> <p style="line-height: 150%"><span lang="EN-US" style="color: black; mso-bidi-font-family: arial">&nbsp;&nbsp;&nbsp; //c</span><span style="color: black; mso-bidi-font-family: arial">被代理的参数<span lang="EN-US"><br> int execue(int c)<br> {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return (_This-&gt;*_deleGate)(c);<br> }<o:p></o:p></span></span></p> <p style="line-height: 150%"><span lang="EN-US" style="color: black; mso-bidi-font-family: arial">};<o:p></o:p></span></p> <p style="line-height: 150%"><span lang="EN-US" style="color: black; mso-bidi-font-family: arial"><br>class B<br>{<br>public:<br> int FunA(int a) {return a + 10;}<br> int FunB(int a) {return a - 10;}<br> B()<br> {<o:p></o:p></span></p> <p style="line-height: 150%"><span lang="EN-US" style="color: black; mso-bidi-font-family: arial"> }<br>};<o:p></o:p></span></p> <p style="line-height: 150%"><span lang="EN-US" style="color: black; mso-bidi-font-family: arial">int _tmain(int argc, _TCHAR* argv[])<br>{<o:p></o:p></span></p> <p style="line-height: 150%"><span lang="EN-US" style="color: black; mso-bidi-font-family: arial"><br> B *objB = new B();<o:p></o:p></span></p> <p style="line-height: 150%"><span lang="EN-US" style="color: black; mso-bidi-font-family: arial"> A&lt;B&gt;&nbsp; delegateObj1(objB, (&amp;B::FunA));<br> A&lt;B&gt;&nbsp; delegateObj2(objB, (&amp;B::FunB));<o:p></o:p></span></p> <p style="line-height: 150%"><span lang="EN-US" style="color: black; mso-bidi-font-family: arial"><br> cout &lt;&lt; delegateObj1.execue(10) &lt;&lt;endl;<br> cout &lt;&lt; delegateObj2.execue(20) &lt;&lt;endl;<o:p></o:p></span></p> <p style="line-height: 150%"><span lang="EN-US" style="color: black; mso-bidi-font-family: arial"> return 0;<o:p></o:p></span></p> <p style="line-height: 150%"><span lang="EN-US" style="color: black; mso-bidi-font-family: arial">}<o:p></o:p></span></p> <p style="line-height: 150%"><span lang="EN-US" style="color: black; mso-bidi-font-family: arial">&nbsp;<o:p></o:p></span></p> <p style="line-height: 150%"><span lang="EN-US" style="color: black; mso-bidi-font-family: arial">&nbsp;<o:p></o:p></span></p> <p style="line-height: 150%"><span lang="EN-US" style="color: black; mso-bidi-font-family: arial">&nbsp;<o:p></o:p></span></p> <p style="line-height: 150%"><span style="color: black; mso-bidi-font-family: arial">看完了感觉如何？以后想要设计一个<span lang="EN-US">callback</span>回调函数是否明朗了许多？<span lang="EN-US"><br></span>再也不需要强行搞个<span lang="EN-US">static</span>约束方法，那么恶心的东西了吧<span lang="EN-US"><o:p></o:p></span></span></p> <p style="line-height: 150%"><span lang="EN-US" style="color: black; mso-bidi-font-family: arial">&nbsp;</span></p> <p style="line-height: 150%"><span lang="EN-US" style="color: black; mso-bidi-font-family: arial"></span>&nbsp;</p> <p style="line-height: 150%"><span lang="EN-US" style="color: black; mso-bidi-font-family: arial"><o:p></o:p></span>&nbsp;</p> <div style="border-right: medium none; padding-right: 0cm; border-top: #dddddd 1pt solid; padding-left: 0cm; padding-bottom: 0cm; border-left: medium none; padding-top: 0cm; border-bottom: medium none; mso-element: para-border-div; mso-border-top-alt: solid #dddddd .75pt"> <p class="postfoot2" style="line-height: 150%"><span lang="EN-US" style="font-size: 12pt; color: black; line-height: 150%; mso-bidi-font-family: arial">posted on 2008-09-29 13:23 <a href="http://www.cppblog.com/tonykee/"><span lang="EN-US" style="color: black"><span lang="EN-US">李侃</span></span></a> </span><span style="font-size: 12pt; color: black; line-height: 150%; mso-bidi-font-family: arial">阅读<span lang="EN-US">(1284) <a href="http://www.cppblog.com/tonykee/archive/2008/09/30/63034.html#Post#Post"><span lang="EN-US" style="color: black"><span lang="EN-US">评论(11)</span></span></a>&nbsp; <a href="http://www.cppblog.com/tonykee/admin/EditPosts.aspx?postid=63034"><span lang="EN-US" style="color: black"><span lang="EN-US">编辑</span></span></a>&nbsp;<a href="http://www.cppblog.com/tonykee/AddToFavorite.aspx?id=63034"><span lang="EN-US" style="color: black"><span lang="EN-US">收藏</span></span></a> <a href="http://www.cppblog.com/tonykee/services/trackbacks/63034.aspx"><span lang="EN-US" style="color: black"><span lang="EN-US">引用</span></span></a> </span>所属分类<span lang="EN-US">: <a href="http://www.cppblog.com/tonykee/category/7264.html"><span lang="EN-US" style="color: black"><span lang="EN-US">杂谈</span></span></a> <o:p></o:p></span></span></p></div> <p class="MsoNormal"><span lang="EN-US" style="font-size: 12pt; color: black; font-family: 宋体; mso-bidi-font-family: arial"><a href="http://www.cppblog.com/images/cppblog_com/woaidongmao/WindowsLiveWriter/C_10617/clip_image001_2.jpg"><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="5" alt="clip_image001" src="http://www.cppblog.com/images/cppblog_com/woaidongmao/WindowsLiveWriter/C_10617/clip_image001_thumb.jpg" width="5" border="0" v:shapes="_x0000_i1025"></a><o:p></o:p></span></p> <div style="border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; padding-bottom: 0cm; margin-left: 7.5pt; border-left: medium none; margin-right: 7.5pt; padding-top: 0cm; border-bottom: #aaaaaa 1pt solid; mso-element: para-border-div; mso-border-bottom-alt: solid #aaaaaa .75pt"> <p class="MsoNormal" style="border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; padding-bottom: 0cm; border-left: medium none; padding-top: 0cm; border-bottom: medium none; mso-border-bottom-alt: solid #aaaaaa .75pt; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto; mso-outline-level: 4; mso-padding-alt: 0cm 0cm 0cm 0cm"><a name="评论"></a><a name="pagedcomment"></a><span style="mso-bookmark: 评论"><b><span style="font-size: 12pt; color: black; font-family: 宋体; mso-bidi-font-family: arial">评论<span lang="EN-US"><o:p></o:p></span></span></b></span></p></div><span style="mso-bookmark: 评论"></span> <p class="MsoNormal" style="margin-bottom: 3pt; line-height: 150%; mso-outline-level: 3"><b><span lang="EN-US" style="font-size: 12pt; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial"><a title="permalink: re: 模版函数指针，C++委托的实现－原创" href="http://www.cppblog.com/tonykee/archive/2008/09/30/63034.html#63039"><span style="color: black">#</span></a>&nbsp;<a name="63039"></a>re: </span></b><b><span style="font-size: 12pt; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial">模版函数指针，<span lang="EN-US">C++</span>委托的实现－原创<span lang="EN-US">&nbsp; <a href="http://www.cppblog.com/tonykee/archive/2008/09/30/63034.html#post"><span lang="EN-US" style="color: black"><span lang="EN-US">回复</span></span></a>&nbsp; <a title="查看该作者发表过的评论" href="http://www.cppblog.com/comment?author=%e4%b8%87%e8%bf%9e%e6%96%87" target="_blank"><span lang="EN-US" style="color: black"><span lang="EN-US">更多评论</span></span></a> <a id="AjaxHolder_Comments_CommentList_ctl00_DeleteLink" href=""></a>&nbsp;&nbsp; <o:p></o:p></span></span></b></p> <p class="MsoNormal" style="line-height: 150%"><span lang="EN-US" style="font-size: 12pt; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial">sigslot <o:p></o:p></span></p> <p class="MsoNormal" style="line-height: 150%"><span lang="EN-US" style="font-size: 12pt; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial">2008-09-29 14:05 | <a id="AjaxHolder_Comments_CommentList_ctl00_NameLink" href="http://www.cppblog.com/wlwlxj/" target="_blank"><span lang="EN-US" style="color: black"><span lang="EN-US">万连文</span></span></a> <o:p></o:p></span></p> <p class="MsoNormal" style="margin-bottom: 3pt; line-height: 150%; mso-outline-level: 3"><b><span lang="EN-US" style="font-size: 12pt; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial"><a title="permalink: re: 模版函数指针，C++委托的实现－原创[未登录]" href="http://www.cppblog.com/tonykee/archive/2008/09/30/63034.html#63041"><span style="color: black">#</span></a>&nbsp;<a name="63041"></a>re: </span></b><b><span style="font-size: 12pt; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial">模版函数指针，<span lang="EN-US">C++</span>委托的实现－原创<span lang="EN-US">[</span>未登录<span lang="EN-US">]&nbsp; <a href="http://www.cppblog.com/tonykee/archive/2008/09/30/63034.html#post"><span lang="EN-US" style="color: black"><span lang="EN-US">回复</span></span></a>&nbsp; <a title="查看该作者发表过的评论" href="http://www.cppblog.com/comment?author=noname" target="_blank"><span lang="EN-US" style="color: black"><span lang="EN-US">更多评论</span></span></a> <a id="AjaxHolder_Comments_CommentList_ctl01_DeleteLink" href=""></a>&nbsp;&nbsp; <o:p></o:p></span></span></b></p> <p class="MsoNormal" style="line-height: 150%"><span lang="EN-US" style="font-size: 12pt; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial">template&lt;typename T&gt; <br>int funA(T * This, int (T::*delegateFun)(int), int c) <br>{ <br>return (This-&gt;*delegateFun)(c); <br>} <br></span><span style="font-size: 12pt; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial">可以算做委托调用的基本原理，还需要保存<span lang="EN-US">This</span>和<span lang="EN-US">delegateFun</span>的值才能称之为委托。 <span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal" style="line-height: 150%"><span lang="EN-US" style="font-size: 12pt; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial">2008-09-29 14:15 | noname <o:p></o:p></span></p> <p class="MsoNormal" style="margin-bottom: 3pt; line-height: 150%; mso-outline-level: 3"><b><span lang="EN-US" style="font-size: 12pt; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial"><a title="permalink: re: 模版函数指针，C++委托的实现－原创" href="http://www.cppblog.com/tonykee/archive/2008/09/30/63034.html#63050"><span style="color: black">#</span></a>&nbsp;<a name="63050"></a>re: </span></b><b><span style="font-size: 12pt; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial">模版函数指针，<span lang="EN-US">C++</span>委托的实现－原创<span lang="EN-US">&nbsp; <a href="http://www.cppblog.com/tonykee/archive/2008/09/30/63034.html#post"><span lang="EN-US" style="color: black"><span lang="EN-US">回复</span></span></a>&nbsp; <a title="查看该作者发表过的评论" href="http://www.cppblog.com/comment?author=%e6%9d%8e%e4%be%83" target="_blank"><span lang="EN-US" style="color: black"><span lang="EN-US">更多评论</span></span></a> <a id="AjaxHolder_Comments_CommentList_ctl02_DeleteLink" href=""></a>&nbsp;&nbsp; <o:p></o:p></span></span></b></p> <p class="MsoNormal" style="line-height: 150%"><span style="font-size: 12pt; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial">做了一点点调整，这个应该就是了 <span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal" style="line-height: 150%"><span lang="EN-US" style="font-size: 12pt; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial">2008-09-29 16:06 | <a id="AjaxHolder_Comments_CommentList_ctl02_NameLink" href="http://www.cppblog.com/tonykee/" target="_blank"><span lang="EN-US" style="color: black"><span lang="EN-US">李侃</span></span></a> <o:p></o:p></span></p> <p class="MsoNormal" style="margin-bottom: 3pt; line-height: 150%; mso-outline-level: 3"><b><span lang="EN-US" style="font-size: 12pt; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial"><a title="permalink: re: 模版函数指针，C++委托的实现－原创[未登录]" href="http://www.cppblog.com/tonykee/archive/2008/09/30/63034.html#63062"><span style="color: black">#</span></a>&nbsp;<a name="63062"></a>re: </span></b><b><span style="font-size: 12pt; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial">模版函数指针，<span lang="EN-US">C++</span>委托的实现－原创<span lang="EN-US">[</span>未登录<span lang="EN-US">]&nbsp; <a href="http://www.cppblog.com/tonykee/archive/2008/09/30/63034.html#post"><span lang="EN-US" style="color: black"><span lang="EN-US">回复</span></span></a>&nbsp; <a title="查看该作者发表过的评论" href="http://www.cppblog.com/comment?author=noname" target="_blank"><span lang="EN-US" style="color: black"><span lang="EN-US">更多评论</span></span></a> <a id="AjaxHolder_Comments_CommentList_ctl03_DeleteLink" href=""></a>&nbsp;&nbsp; <o:p></o:p></span></span></b></p> <p class="MsoNormal" style="line-height: 150%"><span lang="EN-US" style="font-size: 12pt; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial">A&lt;B&gt; delegateObj1(objB, (&amp;B::FunA)); <br></span><span style="font-size: 12pt; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial">在这里类<span lang="EN-US">A</span>必须了解<span lang="EN-US">B</span>的类型，而委托存在的意义在于委托类与被委托的对象之间的无关性，可以参照网上一篇关于<span lang="EN-US">fastdelegate</span>的文章。 <span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal" style="line-height: 150%"><span lang="EN-US" style="font-size: 12pt; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial">2008-09-29 22:24 | noname <o:p></o:p></span></p> <p class="MsoNormal" style="margin-bottom: 3pt; line-height: 150%; mso-outline-level: 3"><b><span lang="EN-US" style="font-size: 12pt; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial"><a title="permalink: re: 模版函数指针，C++委托的实现－原创" href="http://www.cppblog.com/tonykee/archive/2008/09/30/63034.html#63066"><span style="color: black">#</span></a>&nbsp;<a name="63066"></a>re: </span></b><b><span style="font-size: 12pt; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial">模版函数指针，<span lang="EN-US">C++</span>委托的实现－原创<span lang="EN-US">&nbsp; <a href="http://www.cppblog.com/tonykee/archive/2008/09/30/63034.html#post"><span lang="EN-US" style="color: black"><span lang="EN-US">回复</span></span></a>&nbsp; <a title="查看该作者发表过的评论" href="http://www.cppblog.com/comment?author=%e8%b8%8f%e9%9b%aa%e8%b5%a4%e5%85%94" target="_blank"><span lang="EN-US" style="color: black"><span lang="EN-US">更多评论</span></span></a> <a id="AjaxHolder_Comments_CommentList_ctl04_DeleteLink" href=""></a>&nbsp;&nbsp; <o:p></o:p></span></span></b></p> <p class="MsoNormal" style="line-height: 150%"><span style="font-size: 12pt; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial">哈哈～楼主创造力不错！<span lang="EN-US"><br></span>我也干个类似的事，不过，比楼主还是再<span lang="EN-US">"</span>过分<span lang="EN-US">"</span>一些～<span lang="EN-US">:-P<br></span>楼上说得有道理，模板类的解耦是不完全的（虽然一般已经够用），使得<span lang="EN-US">A&lt;B&gt;</span>类只能存放<span lang="EN-US">B</span>的成员函数指针，<span lang="EN-US">A&lt;C&gt;</span>类只能存放<span lang="EN-US">C</span>的成员函数指针。<span lang="EN-US"><br></span>换一下思路，能否在一个对象里边托管多个属于不同的类的成员函数指针？ <span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal" style="line-height: 150%"><span lang="EN-US" style="font-size: 12pt; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial">2008-09-29 23:03 | <a id="AjaxHolder_Comments_CommentList_ctl04_NameLink" href="http://www.cnitblog.com/cockerel/" target="_blank"><span lang="EN-US" style="color: black"><span lang="EN-US">踏雪赤兔</span></span></a> <o:p></o:p></span></p> <p class="MsoNormal" style="margin-bottom: 3pt; line-height: 150%; mso-outline-level: 3"><b><span lang="EN-US" style="font-size: 12pt; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial"><a title="permalink: re: 模版函数指针，C++委托的实现－原创" href="http://www.cppblog.com/tonykee/archive/2008/09/30/63034.html#63075"><span style="color: black">#</span></a>&nbsp;<a name="63075"></a>re: </span></b><b><span style="font-size: 12pt; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial">模版函数指针，<span lang="EN-US">C++</span>委托的实现－原创<span lang="EN-US">&nbsp; <a href="http://www.cppblog.com/tonykee/archive/2008/09/30/63034.html#post"><span lang="EN-US" style="color: black"><span lang="EN-US">回复</span></span></a>&nbsp; <a title="查看该作者发表过的评论" href="http://www.cppblog.com/comment?author=%e6%9d%8e%e4%be%83" target="_blank"><span lang="EN-US" style="color: black"><span lang="EN-US">更多评论</span></span></a> <a id="AjaxHolder_Comments_CommentList_ctl05_DeleteLink" href=""></a>&nbsp;&nbsp; <o:p></o:p></span></span></b></p> <p class="MsoNormal" style="line-height: 150%"><span lang="EN-US" style="font-size: 12pt; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial">fastdelegate </span><span style="font-size: 12pt; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial">还可以，去研究一把 <span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal" style="line-height: 150%"><span lang="EN-US" style="font-size: 12pt; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial">2008-09-30 11:45 | <a id="AjaxHolder_Comments_CommentList_ctl05_NameLink" href="http://www.cppblog.com/tonykee/" target="_blank"><span lang="EN-US" style="color: black"><span lang="EN-US">李侃</span></span></a> <o:p></o:p></span></p> <p class="MsoNormal" style="margin-bottom: 3pt; line-height: 150%; mso-outline-level: 3"><b><span lang="EN-US" style="font-size: 12pt; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial"><a title="permalink: re: 模版函数指针，C++委托的实现－原创[未登录]" href="http://www.cppblog.com/tonykee/archive/2008/09/30/63034.html#63081"><span style="color: black">#</span></a>&nbsp;<a name="63081"></a>re: </span></b><b><span style="font-size: 12pt; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial">模版函数指针，<span lang="EN-US">C++</span>委托的实现－原创<span lang="EN-US">[</span>未登录<span lang="EN-US">]&nbsp; <a href="http://www.cppblog.com/tonykee/archive/2008/09/30/63034.html#post"><span lang="EN-US" style="color: black"><span lang="EN-US">回复</span></span></a>&nbsp; <a title="查看该作者发表过的评论" href="http://www.cppblog.com/comment?author=cppexplore" target="_blank"><span lang="EN-US" style="color: black"><span lang="EN-US">更多评论</span></span></a> <a id="AjaxHolder_Comments_CommentList_ctl06_DeleteLink" href=""></a>&nbsp;&nbsp; <o:p></o:p></span></span></b></p> <p class="MsoNormal" style="line-height: 150%"><span style="font-size: 12pt; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial">非常不错！<span lang="EN-US"> <br></span>强大的消息映射、状态机事件映射都要靠这个才能完美的解决成员函数的问题。 <span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal" style="line-height: 150%"><span lang="EN-US" style="font-size: 12pt; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial">2008-09-30 12:46 | <a id="AjaxHolder_Comments_CommentList_ctl06_NameLink" href="http://www.cppblog.com/cppexplore" target="_blank"><span style="color: black">cppexplore</span></a> <o:p></o:p></span></p> <p class="MsoNormal" style="margin-bottom: 3pt; line-height: 150%; mso-outline-level: 3"><b><span lang="EN-US" style="font-size: 12pt; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial"><a title="permalink: re: 模版函数指针，C++委托的实现－原创" href="http://www.cppblog.com/tonykee/archive/2008/09/30/63034.html#63304"><span style="color: black">#</span></a>&nbsp;<a name="63304"></a>re: </span></b><b><span style="font-size: 12pt; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial">模版函数指针，<span lang="EN-US">C++</span>委托的实现－原创<span lang="EN-US">&nbsp; <a href="http://www.cppblog.com/tonykee/archive/2008/09/30/63034.html#post"><span lang="EN-US" style="color: black"><span lang="EN-US">回复</span></span></a>&nbsp; <a title="查看该作者发表过的评论" href="http://www.cppblog.com/comment?author=adie" target="_blank"><span lang="EN-US" style="color: black"><span lang="EN-US">更多评论</span></span></a> <a id="AjaxHolder_Comments_CommentList_ctl07_DeleteLink" href=""></a>&nbsp;&nbsp; <o:p></o:p></span></span></b></p> <p class="MsoNormal" style="line-height: 150%"><span lang="EN-US" style="font-size: 12pt; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial">A&lt;B&gt; delegateObj1(objB, (&amp;B::FunA)); <br></span><span style="font-size: 12pt; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial">在这里类<span lang="EN-US">A</span>必须了解<span lang="EN-US">B</span>的类型，而委托存在的意义在于委托类与被委托的对象之间的无关性<span lang="EN-US"> <br>----------------------- <br></span>这才是关键 <span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal" style="line-height: 150%"><span lang="EN-US" style="font-size: 12pt; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial">2008-10-06 11:33 | adie <o:p></o:p></span></p> <p class="MsoNormal" style="margin-bottom: 3pt; line-height: 150%; mso-outline-level: 3"><b><span lang="EN-US" style="font-size: 12pt; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial"><a title="permalink: re: 模版函数指针，C++委托的实现－原创" href="http://www.cppblog.com/tonykee/archive/2008/09/30/63034.html#63324"><span style="color: black">#</span></a>&nbsp;<a name="63324"></a>re: </span></b><b><span style="font-size: 12pt; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial">模版函数指针，<span lang="EN-US">C++</span>委托的实现－原创<span lang="EN-US">&nbsp; <a href="http://www.cppblog.com/tonykee/archive/2008/09/30/63034.html#post"><span lang="EN-US" style="color: black"><span lang="EN-US">回复</span></span></a>&nbsp; <a title="查看该作者发表过的评论" href="http://www.cppblog.com/comment?author=Wang+Feng" target="_blank"><span lang="EN-US" style="color: black"><span lang="EN-US">更多评论</span></span></a> <a id="AjaxHolder_Comments_CommentList_ctl08_DeleteLink" href=""></a>&nbsp;&nbsp; <o:p></o:p></span></span></b></p> <p class="MsoNormal" style="line-height: 150%"><span lang="EN-US" style="font-size: 12pt; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial">boost</span><span style="font-size: 12pt; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial">中<span lang="EN-US">bind</span>这样来做：<span lang="EN-US"><br>class button<br>{<br>public:<br><br>boost::function&lt;void&gt; onClick;<br>};<br><br>class player<br>{<br>public:<br><br>void play();<br>void stop();<br>};<br><br>button playButton, stopButton;<br>player thePlayer;<br><br>void connect()<br>{<br>playButton.onClick = boost::bind(&amp;player::play, &amp;thePlayer);<br>stopButton.onClick = boost::bind(&amp;player::stop, &amp;thePlayer);<br>}<o:p></o:p></span></span></p> <p class="MsoNormal" style="line-height: 150%"><span lang="EN-US" style="font-size: 12pt; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial">2008-10-06 16:20 | <a id="AjaxHolder_Comments_CommentList_ctl08_NameLink" href="http://www.cppblog.com/feng/" target="_blank"><span style="color: black">Wang Feng</span></a> <o:p></o:p></span></p> <p class="MsoNormal" style="margin-bottom: 3pt; line-height: 150%; mso-outline-level: 3"><b><span lang="EN-US" style="font-size: 12pt; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial"><a title="permalink: re: 模版函数指针，C++委托的实现－原创" href="http://www.cppblog.com/tonykee/archive/2008/09/30/63034.html#63341"><span style="color: black">#</span></a>&nbsp;<a name="63341"></a>re: </span></b><b><span style="font-size: 12pt; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial">模版函数指针，<span lang="EN-US">C++</span>委托的实现－原创<span lang="EN-US">&nbsp; <a href="http://www.cppblog.com/tonykee/archive/2008/09/30/63034.html#post"><span lang="EN-US" style="color: black"><span lang="EN-US">回复</span></span></a>&nbsp; <a title="查看该作者发表过的评论" href="http://www.cppblog.com/comment?author=%e6%9d%8e%e4%be%83" target="_blank"><span lang="EN-US" style="color: black"><span lang="EN-US">更多评论</span></span></a> <a id="AjaxHolder_Comments_CommentList_ctl09_DeleteLink" href=""></a>&nbsp;&nbsp; <o:p></o:p></span></span></b></p> <p class="MsoNormal" style="line-height: 150%"><span lang="EN-US" style="font-size: 12pt; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial">boost</span><span style="font-size: 12pt; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial">是很好，可有些庞大，目前并不打算使用<span lang="EN-US"> <br></span>我已经加入了<span lang="EN-US">fastdelegate</span>，这个短小精悍，足以解决我的问题了。 <span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal" style="line-height: 150%"><span lang="EN-US" style="font-size: 12pt; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial">2008-10-06 22:14 | <a id="AjaxHolder_Comments_CommentList_ctl09_NameLink" href="http://www.cppblog.com/tonykee/" target="_blank"><span lang="EN-US" style="color: black"><span lang="EN-US">李侃</span></span></a> <o:p></o:p></span></p> <p class="MsoNormal" style="margin-bottom: 3pt; line-height: 150%; mso-outline-level: 3"><b><span lang="EN-US" style="font-size: 12pt; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial"><a title="permalink: re: 模版函数指针，C++委托的实现－原创" href="http://www.cppblog.com/tonykee/archive/2008/09/30/63034.html#63409"><span style="color: black">#</span></a>&nbsp;<a name="63409"></a>re: </span></b><b><span style="font-size: 12pt; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial">模版函数指针，<span lang="EN-US">C++</span>委托的实现－原创<a name="Post"></a><span lang="EN-US">&nbsp; <a href="http://www.cppblog.com/tonykee/archive/2008/09/30/63034.html#post"><span lang="EN-US" style="color: black"><span lang="EN-US">回复</span></span></a>&nbsp; <a title="查看该作者发表过的评论" href="http://www.cppblog.com/comment?author=RichardHe" target="_blank"><span lang="EN-US" style="color: black"><span lang="EN-US">更多评论</span></span></a> <a id="AjaxHolder_Comments_CommentList_ctl10_DeleteLink" href=""></a>&nbsp;&nbsp; <o:p></o:p></span></span></b></p> <p class="MsoNormal" style="line-height: 150%"><span style="font-size: 12pt; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial">听说<span lang="EN-US">BOOST</span>明年加入<span lang="EN-US">C++</span>标准了<span lang="EN-US">!</span>要慢慢去了解下<span lang="EN-US">! <o:p></o:p></span></span></p> <p class="MsoNormal"><span lang="EN-US" style="font-size: 12pt; color: black; font-family: 宋体; mso-bidi-font-family: arial"><o:p>&nbsp;</o:p></span></p><img src ="http://www.cppblog.com/woaidongmao/aggbug/66434.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/woaidongmao/" target="_blank">肥仔</a> 2008-11-09 18:39 <a href="http://www.cppblog.com/woaidongmao/archive/2008/11/09/66434.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C++程序的异常处理技巧</title><link>http://www.cppblog.com/woaidongmao/archive/2008/11/09/66431.html</link><dc:creator>肥仔</dc:creator><author>肥仔</author><pubDate>Sun, 09 Nov 2008 10:08:00 GMT</pubDate><guid>http://www.cppblog.com/woaidongmao/archive/2008/11/09/66431.html</guid><wfw:comment>http://www.cppblog.com/woaidongmao/comments/66431.html</wfw:comment><comments>http://www.cppblog.com/woaidongmao/archive/2008/11/09/66431.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/woaidongmao/comments/commentRss/66431.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/woaidongmao/services/trackbacks/66431.html</trackback:ping><description><![CDATA[<p><span style="font-size: 12pt; color: black; line-height: 150%">　　处理<span lang="EN-US"> C++ </span>中的异常会在语言级别上遇到少许隐含限制，但在某些情况下，您可以绕过它们。学习各种利用异常的方法，您就可以生产更可靠的应用程序。<span lang="EN-US"><?xml:namespace prefix = o /><o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　保留异常来源信息<span lang="EN-US"><o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　在<span lang="EN-US">C++</span>中，无论何时在处理程序内捕获一个异常，关于该异常来源的信息都是不为人知的。异常的具体来源可以提供许多更好地处理该异常的重要信息，或者提供一些可以附加到错误日志的信息，以便以后进行分析。<span lang="EN-US"><o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　为了解决这一问题，可以在抛出异常语句期间，在异常对象的构造函数中生成一个堆栈跟踪。<span lang="EN-US">ExceptionTracer</span>是示范这种行为的一个类。<span lang="EN-US"><o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　清单<span lang="EN-US"> 1. </span>在异常对象构造函数中生成一个堆栈跟踪<span lang="EN-US"><o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">// Sample Program:<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">// Compiler: gcc 3.2.3 20030502<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">// Linux: Red Hat<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">#include <o:p></o:p></span></span><execinfo.h></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">#include <o:p></o:p></span></span><signal.h></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">#include <o:p></o:p></span></span><exception></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">#include <o:p></o:p></span></span><iostream></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">using namespace std;<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">/////////////////////////////////////////////<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">class ExceptionTracer<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">{<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">public:<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">ExceptionTracer()<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">{<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">void * array[25];<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">int nSize = backtrace(array, 25);<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">char ** symbols = backtrace_symbols(array, nSize);<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　　<span lang="EN-US"><o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">for (int i = 0; i &lt; nSize; i++)<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">{<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">cout &lt;&lt; symbols[i] &lt;&lt; endl;<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">}<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">free(symbols);<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">}<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">};<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　管理信号<span lang="EN-US"><o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　每当进程执行一个令人讨厌的动作，以致于<span lang="EN-US"> Linux? </span>内核发出一个信号时，该信号都必须被处理。信号处理程序通常会释放一些重要资源并终止应用程序。在这种情况下，堆栈上的所有对象实例都处于未破坏状态。另一方面，如果这些信号被转换成<span lang="EN-US">C++ </span>异常，那么您可以优雅地调用其构造函数，并安排多层<span lang="EN-US"> catch </span>块，以便更好地处理这些信号。<span lang="EN-US"><o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　清单<span lang="EN-US"> 2 </span>中定义的<span lang="EN-US"> SignalExceptionClass</span>，提供了表示内核可能发出信号的<span lang="EN-US"> C++ </span>异常的抽象。<span lang="EN-US">SignalTranslator </span>是一个基于<span lang="EN-US"> SignalExceptionClass </span>的模板类，它通常用来实现到<span lang="EN-US"> C++ </span>异常的转换。在任何瞬间，只能有一个信号处理程序处理一个活动进程的一个信号。因此，<span lang="EN-US">SignalTranslator </span>采用了<span lang="EN-US"> singleton </span>设计模式。整体概念通过用于<span lang="EN-US"> SIGSEGV </span>的<span lang="EN-US"> SegmentationFault </span>类和用于<span lang="EN-US"> SIGFPE </span>的<span lang="EN-US">FloatingPointException </span>类得到了展示。<span lang="EN-US"><o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　清单<span lang="EN-US"> 2. </span>将信号转换成异常<span lang="EN-US"><o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">template <class signalexceptionclass>class SignalTranslator<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">{<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">private:<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">class SingleTonTranslator<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">{<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">public:<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">SingleTonTranslator()<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">{<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">signal(SignalExceptionClass::GetSignalNumber(),<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">SignalHandler);<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">}<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">static void SignalHandler(int)<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">{<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">throw SignalExceptionClass();<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">}<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">};<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">public:<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">SignalTranslator()<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">{<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">static SingleTonTranslator s_objTranslator;<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">}<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">};<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">// An example for SIGSEGV<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">class SegmentationFault : public ExceptionTracer, public<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">exception<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">{<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">public:<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">static int GetSignalNumber() {return SIGSEGV;}<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">};<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">SignalTranslator<o:p></o:p></span></span><segmentationfault></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">g_objSegmentationFaultTranslator;<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">// An example for SIGFPE<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">class FloatingPointException : public ExceptionTracer, public<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">exception<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">{<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">public:<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">static int GetSignalNumber() {return SIGFPE;}<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">};<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">SignalTranslator<o:p></o:p></span></span><floatingpointexception></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">g_objFloatingPointExceptionTranslator;<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　管理构造函数和析构函数中的异常<span lang="EN-US"><o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　在全局<span lang="EN-US">(</span>静态全局<span lang="EN-US">)</span>变量的构造和析构期间，每个<span lang="EN-US"> ANSI C++ </span>都捕获到异常是不可能的。因此，<span lang="EN-US">ANSI C++ </span>不建议在那些其实例可能被定义为全局实例<span lang="EN-US">(</span>静态全局实例<span lang="EN-US">)</span>的类的构造函数和析构函数中抛出异常。换一种说法就是永远都不要为那些其构造函数和析构函数可能抛出异常的类定义全局<span lang="EN-US">(</span>静态全局<span lang="EN-US">)</span>实例。不过，如果假定有一个特定编译器和一个特定系统，那么可能可以这样做，幸运的是，对于<span lang="EN-US">Linux </span>上的<span lang="EN-US"> GCC</span>，恰好是这种情况。<span lang="EN-US"><o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　使用<span lang="EN-US"> ExceptionHandler </span>类可以展示这一点，该类也采用了<span lang="EN-US"> singleton </span>设计模式。其构造函数注册了一个未捕获的处理程序。因为每次只能有一个未捕获的处理程序处理一个活动进程，构造函数应该只被调用一次，因此要采用<span lang="EN-US"> singleton </span>模式。应该在定义有问题的实际全局<span lang="EN-US">(</span>静态全局<span lang="EN-US">)</span>变量之前定义<span lang="EN-US"> ExceptionHandler </span>的全局<span lang="EN-US">(</span>静态全局<span lang="EN-US">)</span>实例。<span lang="EN-US"><o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　清单<span lang="EN-US"> 3. </span>处理构造函数中的异常<span lang="EN-US"><o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">class ExceptionHandler<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">{<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">private:<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">class SingleTonHandler<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">{<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">public:<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">SingleTonHandler()<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">{<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">set_terminate(Handler);<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">}<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">static void Handler()<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">{<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">// Exception from construction/destruction of global variables try<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">{<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">// re-throw throw;<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">}<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">catch (SegmentationFault &amp;)<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">{<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">cout &lt;&lt; </span>“<span lang="EN-US">SegmentationFault</span>”<span lang="EN-US"> &lt;&lt; endl;<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">}<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">catch (FloatingPointException &amp;)<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">{<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">cout &lt;&lt; </span>“<span lang="EN-US">FloatingPointException</span>”<span lang="EN-US"> &lt;&lt; endl;<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">}<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">catch (...)<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">{<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">cout &lt;&lt; </span>“<span lang="EN-US">Unknown Exception</span>”<span lang="EN-US"> &lt;&lt; endl;<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">}<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">//if this is a thread performing some core activity<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">abort();<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">// else if this is a thread used to service requests<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">// pthread_exit();<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">}<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">};<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">public:<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">ExceptionHandler()<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">{<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">static SingleTonHandler s_objHandler;<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">}<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">};<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">//////////////////////////////////////////////////////////////////////////<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">class A<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">{<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">public:<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">A()<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">{<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">//int i = 0, j = 1/i;<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">*(int *)0 = 0;<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">}<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">};<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">// Before defining any global variable, we define a dummy instance<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">// of ExceptionHandler object to make sure that<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">// ExceptionHandler::SingleTonHandler::SingleTonHandler() is<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">invoked<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">ExceptionHandler g_objExceptionHandler;<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">A g_a;<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">//////////////////////////////////////////////////////////////////////////<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">int main(int argc, char* argv[])<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">{<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">return 0;<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">}<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　处理多线程程序中的异常<span lang="EN-US"><o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　有时一些异常没有被捕获，这将造成进程异常中止。不过很多时候，进程包含多个线程，其中少数线程执行核心应用程序逻辑，同时，其余线程为外部请求提供服务。如果服务线程因编程错误而没有处理某个异常，则会造成整个应用程序崩溃。这一点可能是不受人们欢迎的，因为它会通过向应用程序传送不合法的请求而助长拒绝服务攻击。为了避免这一点，未捕获处理程序可以决定是请求异常中止调用，还是请求线程退出调用。清单<span lang="EN-US">3 </span>中<span lang="EN-US"> ExceptionHandler::SingleTonHandler::Handler() </span>函数的末尾处展示了该处理程序。<span lang="EN-US"><o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　结束语<span lang="EN-US"><o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　我简单地讨论了少许<span lang="EN-US"> C++ </span>编程设计模式，以便更好地执行以下任务：<span lang="EN-US"><o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　·在抛出异常的时候追踪异常的来源。<span lang="EN-US"><o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　·将信号从内核程序转换成<span lang="EN-US"> C++ </span>异常。<span lang="EN-US"><o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　·捕获构造和<span lang="EN-US">/</span>或析构全局变量期间抛出的异常。<span lang="EN-US"><o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　·多线程进程中的异常处理。<span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal"><span lang="EN-US" style="font-size: 12pt; color: black; font-family: 宋体; mso-bidi-font-family: arial"><o:p>&nbsp;</o:p></span></p><img src ="http://www.cppblog.com/woaidongmao/aggbug/66431.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/woaidongmao/" target="_blank">肥仔</a> 2008-11-09 18:08 <a href="http://www.cppblog.com/woaidongmao/archive/2008/11/09/66431.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C++中extern &amp;ldquo;C&amp;rdquo;含义深层探索</title><link>http://www.cppblog.com/woaidongmao/archive/2008/11/09/66430.html</link><dc:creator>肥仔</dc:creator><author>肥仔</author><pubDate>Sun, 09 Nov 2008 10:07:00 GMT</pubDate><guid>http://www.cppblog.com/woaidongmao/archive/2008/11/09/66430.html</guid><wfw:comment>http://www.cppblog.com/woaidongmao/comments/66430.html</wfw:comment><comments>http://www.cppblog.com/woaidongmao/archive/2008/11/09/66430.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/woaidongmao/comments/commentRss/66430.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/woaidongmao/services/trackbacks/66430.html</trackback:ping><description><![CDATA[<p><span lang="EN-US" style="font-size: 12pt; color: black; line-height: 150%">1.</span><span style="font-size: 12pt; color: black; line-height: 150%">引言<span lang="EN-US"><?xml:namespace prefix = o /><o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">C++</span>语言的创建初衷是“<span lang="EN-US">a better C</span>”，但是这并不意味着<span lang="EN-US">C++</span>中类似<span lang="EN-US">C</span>语言的全局变量和函数所采用的编译和连接方式与<span lang="EN-US">C</span>语言完全相同。作为一种欲与<span lang="EN-US">C</span>兼容的语言，<span lang="EN-US">C++</span>保留了一部分过程式语言的特点<span lang="EN-US">(</span>被世人称为“不彻底地面向对象”<span lang="EN-US">)</span>，因而它可以定义不属于任何类的全局变量和函数。但是，<span lang="EN-US">C++</span>毕竟是一种面向对象的程序设计语言，为了支持函数的重载，<span lang="EN-US">C++</span>对全局函数的处理方式与<span lang="EN-US">C</span>有明显的不同。<span lang="EN-US"><o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">2.</span>从标准头文件说起<span lang="EN-US"><o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　某企业曾经给出如下的一道面试题：<span lang="EN-US"><o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　面试题<span lang="EN-US">:</span>为什么标准头文件都有类似以下的结构？<span lang="EN-US"><o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">#ifndef __INCvxWorksh<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">#define __INCvxWorksh<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">#ifdef __cplusplus<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">extern "C" {<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">#endif<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">/*...*/<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">#ifdef __cplusplus<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">}<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">#endif<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">#endif /* __INCvxWorksh */<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　分析<span lang="EN-US"><o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　显然，头文件中的编译宏“<span lang="EN-US">#ifndef __INCvxWorksh</span>、<span lang="EN-US">#define __INCvxWorksh</span>、<span lang="EN-US">#endif</span>” 的作用是防止该头文件被重复引用。<span lang="EN-US"><o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　那么<span lang="EN-US"><o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">#ifdef __cplusplus<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">extern "C" {<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">#endif<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">#ifdef __cplusplus<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">}<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">#endif<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　的作用又是什么呢？我们将在下文一一道来。<span lang="EN-US"><o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">3.</span>深层揭密<span lang="EN-US">extern "C"<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">extern "C" </span>包含双重含义，从字面上即可得到：首先，被它修饰的目标是“<span lang="EN-US">extern</span>”的；其次，被它修饰的目标是“<span lang="EN-US">C</span>”的。让我们来详细解读这两重含义。<span lang="EN-US"><o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　被<span lang="EN-US">extern "C"</span>限定的函数或变量是<span lang="EN-US">extern</span>类型的；<span lang="EN-US"><o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">extern</span>是<span lang="EN-US">C/C++</span>语言中表明函数和全局变量作用范围<span lang="EN-US">(</span>可见性<span lang="EN-US">)</span>的关键字，该关键字告诉编译器，其声明的函数和变量可以在本模块或其它模块中使用。记住，下列语句：<span lang="EN-US"><o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">extern int a;<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　仅仅是一个变量的声明，其并不是在定义变量<span lang="EN-US">a</span>，并未为<span lang="EN-US">a</span>分配内存空间。变量<span lang="EN-US">a</span>在所有模块中作为一种全局变量只能被定义一次，否则会出现连接错误。<span lang="EN-US"><o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　通常，在模块的头文件中对本模块提供给其它模块引用的函数和全局变量以关键字<span lang="EN-US">extern</span>声明。例如，如果模块<span lang="EN-US">B</span>欲引用该模块<span lang="EN-US">A</span>中定义的全局变量和函数时只需包含模块<span lang="EN-US">A</span>的头文件即可。这样，模块<span lang="EN-US">B</span>中调用模块<span lang="EN-US">A</span>中的函数时，在编译阶段，模块<span lang="EN-US">B</span>虽然找不到该函数，但是并不会报错；它会在连接阶段中从模块<span lang="EN-US">A</span>编译生成的目标代码中找到此函数。<span lang="EN-US"><o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　与<span lang="EN-US">extern</span>对应的关键字是<span lang="EN-US">static</span>，被它修饰的全局变量和函数只能在本模块中使用。因此，一个函数或变量只可能被本模块使用时，其不可能被<span lang="EN-US">extern </span>“<span lang="EN-US">C</span>”修饰。<span lang="EN-US"><o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　被<span lang="EN-US">extern "C"</span>修饰的变量和函数是按照<span lang="EN-US">C</span>语言方式编译和连接的；<span lang="EN-US"><o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　未加<span lang="EN-US">extern </span>“<span lang="EN-US">C</span>”声明时的编译方式<span lang="EN-US"><o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　首先看看<span lang="EN-US">C++</span>中对类似<span lang="EN-US">C</span>的函数是怎样编译的。<span lang="EN-US"><o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　作为一种面向对象的语言，<span lang="EN-US">C++</span>支持函数重载，而过程式语言<span lang="EN-US">C</span>则不支持。函数被<span lang="EN-US">C++</span>编译后在符号库中的名字与<span lang="EN-US">C</span>语言的不同。例如，假设某个函数的原型为：<span lang="EN-US"><o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">void foo( int x, int y );<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　该函数被<span lang="EN-US">C</span>编译器编译后在符号库中的名字为<span lang="EN-US">_foo</span>，而<span lang="EN-US">C++</span>编译器则会产生像<span lang="EN-US">_foo_int_int</span>之类的名字<span lang="EN-US">(</span>不同的编译器可能生成的名字不同，但是都采用了相同的机制，生成的新名字称为“<span lang="EN-US">mangled name</span>”<span lang="EN-US">)</span>。<span lang="EN-US"><o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">foo_int_int </span>这样的名字包含了函数名、函数参数数量及类型信息，<span lang="EN-US">C++</span>就是靠这种机制来实现函数重载的。例如，在<span lang="EN-US">C++</span>中，函数<span lang="EN-US">void foo( int x, int y )</span>与<span lang="EN-US">void foo( int x, float y )</span>编译生成的符号是不相同的，后者为<span lang="EN-US">_foo_int_float</span>。<span lang="EN-US"><o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　同样地，<span lang="EN-US">C++</span>中的变量除支持局部变量外，还支持类成员变量和全局变量。用户所编写程序的类成员变量可能与全局变量同名，我们以<span lang="EN-US">"."</span>来区分。而本质上，编译器在进行编译时，与函数的处理相似，也为类中的变量取了一个独一无二的名字，这个名字与用户程序中同名的全局变量名字不同。<span lang="EN-US"><o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　未加<span lang="EN-US">extern "C"</span>声明时的连接方式<span lang="EN-US"><o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　假设在<span lang="EN-US">C++</span>中，模块<span lang="EN-US">A</span>的头文件如下：<span lang="EN-US"><o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">// </span>模块<span lang="EN-US">A</span>头文件　<span lang="EN-US">moduleA.h<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">#ifndef MODULE_A_H<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">#define MODULE_A_H<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">int foo( int x, int y );<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">#endif<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　在模块<span lang="EN-US">B</span>中引用该函数：<span lang="EN-US"><o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">// </span>模块<span lang="EN-US">B</span>实现文件　<span lang="EN-US">moduleB.cpp<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">#include "moduleA.h"<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">foo(2,3);<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　实际上，在连接阶段，连接器会从模块<span lang="EN-US">A</span>生成的目标文件<span lang="EN-US">moduleA.obj</span>中寻找<span lang="EN-US">_foo_int_int</span>这样的符号！<span lang="EN-US"><o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　加<span lang="EN-US">extern "C"</span>声明后的编译和连接方式<span lang="EN-US"><o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　加<span lang="EN-US">extern "C"</span>声明后，模块<span lang="EN-US">A</span>的头文件变为：<span lang="EN-US"><o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">// </span>模块<span lang="EN-US">A</span>头文件　<span lang="EN-US">moduleA.h<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">#ifndef MODULE_A_H<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">#define MODULE_A_H<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">extern "C" int foo( int x, int y );<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">#endif<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　在模块<span lang="EN-US">B</span>的实现文件中仍然调用<span lang="EN-US">foo( 2,3 )</span>，其结果是：<span lang="EN-US"><o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">(1)</span>模块<span lang="EN-US">A</span>编译生成<span lang="EN-US">foo</span>的目标代码时，没有对其名字进行特殊处理，采用了<span lang="EN-US">C</span>语言的方式；<span lang="EN-US"><o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">(2)</span>连接器在为模块<span lang="EN-US">B</span>的目标代码寻找<span lang="EN-US">foo(2,3)</span>调用时，寻找的是未经修改的符号名<span lang="EN-US">_foo</span>。<span lang="EN-US"><o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　如果在模块<span lang="EN-US">A</span>中函数声明了<span lang="EN-US">foo</span>为<span lang="EN-US">extern "C"</span>类型，而模块<span lang="EN-US">B</span>中包含的是<span lang="EN-US">extern int foo( int x, int y ) </span>，则模块<span lang="EN-US">B</span>找不到模块<span lang="EN-US">A</span>中的函数；反之亦然。<span lang="EN-US"><o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　所以，可以用一句话概括<span lang="EN-US">extern </span>“<span lang="EN-US">C</span>”这个声明的真实目的<span lang="EN-US">(</span>任何语言中的任何语法特性的诞生都不是随意而为的，来源于真实世界的需求驱动。我们在思考问题时，不能只停留在这个语言是怎么做的，还要问一问它为什么要这么做，动机是什么，这样我们可以更深入地理解许多问题<span lang="EN-US">)</span>：<span lang="EN-US"><o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　实现<span lang="EN-US">C++</span>与<span lang="EN-US">C</span>及其它语言的混合编程。<span lang="EN-US"><o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　明白了<span lang="EN-US">C++</span>中<span lang="EN-US">extern "C"</span>的设立动机，我们下面来具体分析<span lang="EN-US">extern "C"</span>通常的使用技巧。<span lang="EN-US"><o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">4.extern "C"</span>的惯用法<span lang="EN-US"><o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">(1)</span>在<span lang="EN-US">C++</span>中引用<span lang="EN-US">C</span>语言中的函数和变量，在包含<span lang="EN-US">C</span>语言头文件<span lang="EN-US">(</span>假设为<span lang="EN-US">cExample.h)</span>时，需进行下列处理：<span lang="EN-US"><o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">extern "C"<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">{<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">#include "cExample.h"<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">}<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　而在<span lang="EN-US">C</span>语言的头文件中，对其外部函数只能指定为<span lang="EN-US">extern</span>类型，<span lang="EN-US">C</span>语言中不支持<span lang="EN-US">extern "C"</span>声明，在<span lang="EN-US">.c</span>文件中包含了<span lang="EN-US">extern "C"</span>时会出现编译语法错误。<span lang="EN-US"><o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　笔者编写的<span lang="EN-US">C++</span>引用<span lang="EN-US">C</span>函数例子工程中包含的三个文件的源代码如下：<span lang="EN-US"><o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">/* c</span>语言头文件：<span lang="EN-US">cExample.h */<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">#ifndef C_EXAMPLE_H<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">#define C_EXAMPLE_H<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">extern int add(int x,int y);<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">#endif<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">/* c</span>语言实现文件：<span lang="EN-US">cExample.c */<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">#include "cExample.h"<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">int add( int x, int y )<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">{<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">return x + y;<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">}<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">// c++</span>实现文件，调用<span lang="EN-US">add</span>：<span lang="EN-US">cppFile.cpp<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">extern "C"<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">{<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">#include "cExample.h"<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">}<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">int main(int argc, char* argv[])<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">{<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">add(2,3);<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">return 0;<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">}<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　如果<span lang="EN-US">C++</span>调用一个<span lang="EN-US">C</span>语言编写的<span lang="EN-US">.DLL</span>时，当包括<span lang="EN-US">.DLL</span>的头文件或声明接口函数时，应加<span lang="EN-US">extern "C" {</span>　<span lang="EN-US">}</span>。<span lang="EN-US"><o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">(2)</span>在<span lang="EN-US">C</span>中引用<span lang="EN-US">C++</span>语言中的函数和变量时，<span lang="EN-US">C++</span>的头文件需添加<span lang="EN-US">extern "C"</span>，但是在<span lang="EN-US">C</span>语言中不能直接引用声明了<span lang="EN-US">extern "C"</span>的该头文件，应该仅将<span lang="EN-US">C</span>文件中将<span lang="EN-US">C++</span>中定义的<span lang="EN-US">extern "C"</span>函数声明为<span lang="EN-US">extern</span>类型。<span lang="EN-US"><o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　笔者编写的<span lang="EN-US">C</span>引用<span lang="EN-US">C++</span>函数例子工程中包含的三个文件的源代码如下：<span lang="EN-US"><o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">//C++</span>头文件<span lang="EN-US"> cppExample.h<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">#ifndef CPP_EXAMPLE_H<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">#define CPP_EXAMPLE_H<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">extern "C" int add( int x, int y );<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">#endif<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">//C++</span>实现文件<span lang="EN-US"> cppExample.cpp<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">#include "cppExample.h"<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">int add( int x, int y )<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">{<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">return x + y;<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">}<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">/* C</span>实现文件<span lang="EN-US"> cFile.c<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">/* </span>这样会编译出错：<span lang="EN-US">#include "cExample.h" */<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">extern int add( int x, int y );<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">int main( int argc, char* argv[] )<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">{<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">add( 2, 3 );<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">return 0;<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　<span lang="EN-US">}<o:p></o:p></span></span></p> <p><span style="font-size: 12pt; color: black; line-height: 150%">　　如果深入理解了第<span lang="EN-US">3</span>节中所阐述的<span lang="EN-US">extern "C"</span>在编译和连接阶段发挥的作用，就能真正理解本节所阐述的从<span lang="EN-US">C++</span>引用<span lang="EN-US">C</span>函数和<span lang="EN-US">C</span>引用<span lang="EN-US">C++</span>函数的惯用法。<span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal"><span lang="EN-US" style="font-size: 12pt; color: black; font-family: 宋体; mso-bidi-font-family: arial"><o:p>&nbsp;</o:p></span></p><img src ="http://www.cppblog.com/woaidongmao/aggbug/66430.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/woaidongmao/" target="_blank">肥仔</a> 2008-11-09 18:07 <a href="http://www.cppblog.com/woaidongmao/archive/2008/11/09/66430.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>sscanf函数的高级用法</title><link>http://www.cppblog.com/woaidongmao/archive/2008/11/08/66313.html</link><dc:creator>肥仔</dc:creator><author>肥仔</author><pubDate>Sat, 08 Nov 2008 04:12:00 GMT</pubDate><guid>http://www.cppblog.com/woaidongmao/archive/2008/11/08/66313.html</guid><wfw:comment>http://www.cppblog.com/woaidongmao/comments/66313.html</wfw:comment><comments>http://www.cppblog.com/woaidongmao/archive/2008/11/08/66313.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/woaidongmao/comments/commentRss/66313.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/woaidongmao/services/trackbacks/66313.html</trackback:ping><description><![CDATA[<p class="MsoNormal" style="text-align: left; mso-margin-top-alt: auto; mso-pagination: widow-orphan; mso-margin-bottom-alt: auto" align="left"><span style="font-size: 12pt; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">　　大家都知道<span lang="EN-US">sscanf</span>是一个很好用的函数，利用它可以从字符串中取出整数、浮点数和字符串等等。它的使用方法简单，特别对于整数和浮点数来说。但新手可能并不知道处理字符串时的一些高级用法，这里做个简要说明吧。<span lang="EN-US"><?xml:namespace prefix = o /><o:p></o:p></span></span></p> <p class="MsoNormal" style="text-align: left; mso-margin-top-alt: auto; mso-pagination: widow-orphan; mso-margin-bottom-alt: auto" align="left"><span style="font-size: 12pt; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">　　<span lang="EN-US">1. </span>常见用法。<span lang="EN-US"><o:p></o:p></span></span></p> <div align="center"> <table class="MsoNormalTable" style="width: 95%; mso-cellspacing: 0cm; mso-padding-alt: 4.5pt 4.5pt 4.5pt 4.5pt" cellspacing="0" cellpadding="0" width="95%" border="0"> <tbody> <tr style="mso-yfti-irow: 0; mso-yfti-firstrow: yes; mso-yfti-lastrow: yes"> <td style="padding-right: 4.5pt; padding-left: 4.5pt; background: #f3f3f3; padding-bottom: 4.5pt; padding-top: 4.5pt"> <p class="MsoNormal" style="text-align: left; mso-pagination: widow-orphan" align="left"><b><span style="font-size: 12pt; color: #990000; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">以下是引用片段：</span></b><span lang="EN-US" style="font-size: 12pt; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><br></span><span style="font-size: 12pt; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">　　<span lang="EN-US">char str[512] = {0}; <br></span>　　<span lang="EN-US">sscanf("123456 ", "%s", str); <br></span>　　<span lang="EN-US">printf("str=%s\n", str);<o:p></o:p></span></span></p></td></tr></tbody></table></div> <p class="MsoNormal" style="text-align: left; mso-margin-top-alt: auto; mso-pagination: widow-orphan; mso-margin-bottom-alt: auto" align="left"><span style="font-size: 12pt; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">　　<span lang="EN-US">2. </span>取指定长度的字符串。如在下例中，取最大长度为<span lang="EN-US">4</span>字节的字符串。<span lang="EN-US"><o:p></o:p></span></span></p> <div align="center"> <table class="MsoNormalTable" style="width: 95%; mso-cellspacing: 0cm; mso-padding-alt: 4.5pt 4.5pt 4.5pt 4.5pt" cellspacing="0" cellpadding="0" width="95%" border="0"> <tbody> <tr style="mso-yfti-irow: 0; mso-yfti-firstrow: yes; mso-yfti-lastrow: yes"> <td style="padding-right: 4.5pt; padding-left: 4.5pt; background: #f3f3f3; padding-bottom: 4.5pt; padding-top: 4.5pt"> <p class="MsoNormal" style="text-align: left; mso-pagination: widow-orphan" align="left"><b><span style="font-size: 12pt; color: #990000; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">以下是引用片段：</span></b><span lang="EN-US" style="font-size: 12pt; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><br></span><span style="font-size: 12pt; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">　　<span lang="EN-US">sscanf("123456 ", "%4s", str); <br></span>　　<span lang="EN-US">printf("str=%s\n", str);<o:p></o:p></span></span></p></td></tr></tbody></table></div> <p class="MsoNormal" style="text-align: left; mso-margin-top-alt: auto; mso-pagination: widow-orphan; mso-margin-bottom-alt: auto" align="left"><span style="font-size: 12pt; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">　　<span lang="EN-US">3. </span>取到指定字符为止的字符串。如在下例中，取遇到空格为止字符串。<span lang="EN-US"><o:p></o:p></span></span></p> <div align="center"> <table class="MsoNormalTable" style="width: 95%; mso-cellspacing: 0cm; mso-padding-alt: 4.5pt 4.5pt 4.5pt 4.5pt" cellspacing="0" cellpadding="0" width="95%" border="0"> <tbody> <tr style="mso-yfti-irow: 0; mso-yfti-firstrow: yes; mso-yfti-lastrow: yes"> <td style="padding-right: 4.5pt; padding-left: 4.5pt; background: #f3f3f3; padding-bottom: 4.5pt; padding-top: 4.5pt"> <p class="MsoNormal" style="text-align: left; mso-pagination: widow-orphan" align="left"><b><span style="font-size: 12pt; color: #990000; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">以下是引用片段：</span></b><span lang="EN-US" style="font-size: 12pt; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><br></span><span style="font-size: 12pt; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">　　<span lang="EN-US">sscanf("123456 abcdedf", "%[^ ]", str); <br></span>　　<span lang="EN-US">printf("str=%s\n", str);<o:p></o:p></span></span></p></td></tr></tbody></table></div> <p class="MsoNormal" style="text-align: left; mso-margin-top-alt: auto; mso-pagination: widow-orphan; mso-margin-bottom-alt: auto" align="left"><span style="font-size: 12pt; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">　　<span lang="EN-US">4. </span>取仅包含指定字符集的字符串。如在下例中，取仅包含<span lang="EN-US">1</span>到<span lang="EN-US">9</span>和小写字母的字符串。<span lang="EN-US"><o:p></o:p></span></span></p> <div align="center"> <table class="MsoNormalTable" style="width: 95%; mso-cellspacing: 0cm; mso-padding-alt: 4.5pt 4.5pt 4.5pt 4.5pt" cellspacing="0" cellpadding="0" width="95%" border="0"> <tbody> <tr style="mso-yfti-irow: 0; mso-yfti-firstrow: yes; mso-yfti-lastrow: yes"> <td style="padding-right: 4.5pt; padding-left: 4.5pt; background: #f3f3f3; padding-bottom: 4.5pt; padding-top: 4.5pt"> <p class="MsoNormal" style="text-align: left; mso-pagination: widow-orphan" align="left"><b><span style="font-size: 12pt; color: #990000; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">以下是引用片段：</span></b><span lang="EN-US" style="font-size: 12pt; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><br></span><span style="font-size: 12pt; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">　　<span lang="EN-US">sscanf("123456abcdedfBCDEF", "%[1<?xml:namespace prefix = st1 /><st1:chmetcnv w:st="on" tcsc="0" numbertype="1" negative="True" hasspace="False" sourcevalue="9" unitname="a">-9a</st1:chmetcnv>-z]", str); <br></span>　　<span lang="EN-US">printf("str=%s\n", str);<o:p></o:p></span></span></p></td></tr></tbody></table></div> <p class="MsoNormal" style="text-align: left; mso-margin-top-alt: auto; mso-pagination: widow-orphan; mso-margin-bottom-alt: auto" align="left"><span style="font-size: 12pt; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">　　<span lang="EN-US">5. </span>取到指定字符集为止的字符串。如在下例中，取遇到大写字母为止的字符串。<span lang="EN-US"><o:p></o:p></span></span></p> <div align="center"> <table class="MsoNormalTable" style="width: 95%; mso-cellspacing: 0cm; mso-padding-alt: 4.5pt 4.5pt 4.5pt 4.5pt" cellspacing="0" cellpadding="0" width="95%" border="0"> <tbody> <tr style="mso-yfti-irow: 0; mso-yfti-firstrow: yes; mso-yfti-lastrow: yes"> <td style="padding-right: 4.5pt; padding-left: 4.5pt; background: #f3f3f3; padding-bottom: 4.5pt; padding-top: 4.5pt"> <p class="MsoNormal" style="text-align: left; mso-pagination: widow-orphan" align="left"><b><span style="font-size: 12pt; color: #990000; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">以下是引用片段：</span></b><span lang="EN-US" style="font-size: 12pt; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><br></span><span style="font-size: 12pt; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">　　<span lang="EN-US">sscanf("123456abcdedfBCDEF", "%[^A-Z]", str); <br></span>　　<span lang="EN-US">printf("str=%s\n", str);<o:p></o:p></span></span></p></td></tr></tbody></table></div> <p class="MsoNormal" style="text-align: left" align="left"><span lang="EN-US" style="font-size: 12pt; font-family: 宋体; mso-bidi-font-family: arial"><o:p>&nbsp;</o:p></span></p><img src ="http://www.cppblog.com/woaidongmao/aggbug/66313.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/woaidongmao/" target="_blank">肥仔</a> 2008-11-08 12:12 <a href="http://www.cppblog.com/woaidongmao/archive/2008/11/08/66313.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C++编译器如何实现异常处理</title><link>http://www.cppblog.com/woaidongmao/archive/2008/11/08/66312.html</link><dc:creator>肥仔</dc:creator><author>肥仔</author><pubDate>Sat, 08 Nov 2008 04:02:00 GMT</pubDate><guid>http://www.cppblog.com/woaidongmao/archive/2008/11/08/66312.html</guid><wfw:comment>http://www.cppblog.com/woaidongmao/comments/66312.html</wfw:comment><comments>http://www.cppblog.com/woaidongmao/archive/2008/11/08/66312.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/woaidongmao/comments/commentRss/66312.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/woaidongmao/services/trackbacks/66312.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 与传统语言相比，C++的一项革命性创新就是它支持异常处理。传统的错误处理方式经常满足不了要求，而异常处理则是一个极好的替代解决方案。它将正常代码和错误处理代码清晰的划分开来，程序变得非常干净并且容易维护。本文讨论了编译器如何实现异常处理。我将假定你已经熟悉异常处理的语法和机制。本文还提供了一个用于VC++的异常处理库，要用库中的处理程序替换掉VC++提供的那个，你只需要调用下面这个函数：     ...&nbsp;&nbsp;<a href='http://www.cppblog.com/woaidongmao/archive/2008/11/08/66312.html'>阅读全文</a><img src ="http://www.cppblog.com/woaidongmao/aggbug/66312.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/woaidongmao/" target="_blank">肥仔</a> 2008-11-08 12:02 <a href="http://www.cppblog.com/woaidongmao/archive/2008/11/08/66312.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C/C++编译过程的9个阶段</title><link>http://www.cppblog.com/woaidongmao/archive/2008/11/08/66311.html</link><dc:creator>肥仔</dc:creator><author>肥仔</author><pubDate>Sat, 08 Nov 2008 03:55:00 GMT</pubDate><guid>http://www.cppblog.com/woaidongmao/archive/2008/11/08/66311.html</guid><wfw:comment>http://www.cppblog.com/woaidongmao/comments/66311.html</wfw:comment><comments>http://www.cppblog.com/woaidongmao/archive/2008/11/08/66311.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/woaidongmao/comments/commentRss/66311.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/woaidongmao/services/trackbacks/66311.html</trackback:ping><description><![CDATA[<p class="MsoNormal" style="line-height: 150%"><span style="font-size: 12pt; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial">标准<span lang="EN-US">C</span>和<span lang="EN-US">C++</span>将编译过程定义为<span lang="EN-US">9</span>个阶段<span lang="EN-US">(Phases of Translation)</span>：<span lang="EN-US"><?xml:namespace prefix = o /><o:p></o:p></span></span></p> <p class="MsoNormal" style="line-height: 150%"><span lang="EN-US" style="font-size: 12pt; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial"><o:p>&nbsp;</o:p></span></p> <p class="MsoNormal" style="line-height: 150%"><span lang="EN-US" style="font-size: 12pt; color: blue; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial">1.</span><span style="font-size: 12pt; color: blue; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial">字符映射<span lang="EN-US">(Character Mapping)<o:p></o:p></span></span></p> <p class="MsoNormal" style="line-height: 150%"><span lang="EN-US" style="font-size: 12pt; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span></span><span style="font-size: 12pt; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial">文件中的物理源字符被映射到源字符集中，其中包括三字符运算符的替换、控制字符<span lang="EN-US">(</span>行尾的回车换行<span lang="EN-US">)</span>的替换。许多非美式键盘不支持基本源字符集中的一些字符，文件中可用三字符来代替这些基本源字符，以<span lang="EN-US">??</span>为前导。但如果所用键盘是美式键盘，有些编译器可能不对三字符进行查找和替换，需要增加<span lang="EN-US">-trigraphs</span>编译参数。在<span lang="EN-US">C++</span>程序中，任何不在基本源字符集中的字符都被它的通用字符名替换。<span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal" style="line-height: 150%"><span lang="EN-US" style="font-size: 12pt; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial"><o:p>&nbsp;</o:p></span></p> <p class="MsoNormal" style="line-height: 150%"><span lang="EN-US" style="font-size: 12pt; color: blue; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial">2.</span><span style="font-size: 12pt; color: blue; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial">行合并<span lang="EN-US">(Line Splicing)<o:p></o:p></span></span></p> <p class="MsoNormal" style="line-height: 150%"><span lang="EN-US" style="font-size: 12pt; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span></span><span style="font-size: 12pt; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial">以反斜杠<span lang="EN-US">\</span>结束的行和它接下来的行合并。<span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal" style="line-height: 150%"><span lang="EN-US" style="font-size: 12pt; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial"><o:p>&nbsp;</o:p></span></p> <p class="MsoNormal" style="line-height: 150%"><span lang="EN-US" style="font-size: 12pt; color: blue; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial">3.</span><span style="font-size: 12pt; color: blue; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial">标记化<span lang="EN-US">(Tokenization)<o:p></o:p></span></span></p> <p class="MsoNormal" style="line-height: 150%"><span lang="EN-US" style="font-size: 12pt; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span></span><span style="font-size: 12pt; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial">每一条注释被一个单独的空字符所替换。<span lang="EN-US">C++</span>双字符运算符被识别为标记<span lang="EN-US">(</span>为了开发可读性更强的程序，<span lang="EN-US">C++</span>为非<span lang="EN-US">ASCII</span>码开发者定义了一套双字符运算符集和新的保留字集<span lang="EN-US">)</span>。源代码被分析成预处理标记。<span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal" style="line-height: 150%"><span lang="EN-US" style="font-size: 12pt; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial"><o:p>&nbsp;</o:p></span></p> <p class="MsoNormal" style="line-height: 150%"><span lang="EN-US" style="font-size: 12pt; color: blue; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial">4.</span><span style="font-size: 12pt; color: blue; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial">预处理<span lang="EN-US">(Preprocessing)<o:p></o:p></span></span></p> <p class="MsoNormal" style="line-height: 150%"><span lang="EN-US" style="font-size: 12pt; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span></span><span style="font-size: 12pt; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial">调用预处理指令并扩展宏。使用<span lang="EN-US">#include</span>指令包含的文件，<span style="color: red">重复步骤<span lang="EN-US">1</span>到<span lang="EN-US">4</span>。上述四个阶段统称为预处理阶段。<span lang="EN-US"><o:p></o:p></span></span></span></p> <p class="MsoNormal" style="line-height: 150%"><span lang="EN-US" style="font-size: 12pt; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial"><o:p>&nbsp;</o:p></span></p> <p class="MsoNormal" style="line-height: 150%"><span lang="EN-US" style="font-size: 12pt; color: blue; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial">5.</span><span style="font-size: 12pt; color: blue; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial">字符集映射<span lang="EN-US">(Character-set Mapping)<o:p></o:p></span></span></p> <p class="MsoNormal" style="line-height: 150%"><span lang="EN-US" style="font-size: 12pt; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span></span><span style="font-size: 12pt; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial">源字符集成员、转义序列被转换成等价的执行字符集成员。例如：<?xml:namespace prefix = st1 /><st1:personname w:st="on"><span lang="EN-US">'</span></st1:personname><span lang="EN-US">\a<st1:personname w:st="on">'</st1:personname></span>在<span lang="EN-US">ASCII</span>环境下会被转换成值为一个字节，值为<span lang="EN-US">7</span>。<span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal" style="line-height: 150%"><span lang="EN-US" style="font-size: 12pt; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial"><o:p>&nbsp;</o:p></span></p> <p class="MsoNormal" style="line-height: 150%"><span lang="EN-US" style="font-size: 12pt; color: blue; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial">6.</span><span style="font-size: 12pt; color: blue; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial">字符串连接<span lang="EN-US">(String Concatenation)<o:p></o:p></span></span></p> <p class="MsoNormal" style="line-height: 150%"><span lang="EN-US" style="font-size: 12pt; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span></span><span style="font-size: 12pt; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial">相邻的字符串被连接。例如：<span lang="EN-US">"""hahaha""huohuohuo"</span>将成为<span lang="EN-US">"hahahahuohuohuo"</span>。<span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal" style="line-height: 150%"><span lang="EN-US" style="font-size: 12pt; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial"><o:p>&nbsp;</o:p></span></p> <p class="MsoNormal" style="line-height: 150%"><span lang="EN-US" style="font-size: 12pt; color: blue; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial">7.</span><span style="font-size: 12pt; color: blue; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial">翻译<span lang="EN-US">(Translation)<o:p></o:p></span></span></p> <p class="MsoNormal" style="line-height: 150%"><span lang="EN-US" style="font-size: 12pt; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span></span><span style="font-size: 12pt; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial">进行语法和语义分析编译，并翻译成目标代码。<span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal" style="line-height: 150%"><span lang="EN-US" style="font-size: 12pt; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial"><o:p>&nbsp;</o:p></span></p> <p class="MsoNormal" style="line-height: 150%"><span lang="EN-US" style="font-size: 12pt; color: blue; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial">8.</span><span style="font-size: 12pt; color: blue; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial">处理模板<span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal" style="line-height: 150%"><span lang="EN-US" style="font-size: 12pt; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span></span><span style="font-size: 12pt; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial">处理模板实例。<span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal" style="line-height: 150%"><span lang="EN-US" style="font-size: 12pt; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial"><o:p>&nbsp;</o:p></span></p> <p class="MsoNormal" style="line-height: 150%"><span lang="EN-US" style="font-size: 12pt; color: blue; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial">9.</span><span style="font-size: 12pt; color: blue; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial">连接<span lang="EN-US">(Linkage)<o:p></o:p></span></span></p> <p class="MsoNormal" style="line-height: 150%"><span lang="EN-US" style="font-size: 12pt; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span></span><span style="font-size: 12pt; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial">解决外部引用的问题，准备好程序映像以便执行。<span lang="EN-US"><o:p></o:p></span></span></p><img src ="http://www.cppblog.com/woaidongmao/aggbug/66311.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/woaidongmao/" target="_blank">肥仔</a> 2008-11-08 11:55 <a href="http://www.cppblog.com/woaidongmao/archive/2008/11/08/66311.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>不用临时变量也可以交换变量的值</title><link>http://www.cppblog.com/woaidongmao/archive/2008/11/07/66256.html</link><dc:creator>肥仔</dc:creator><author>肥仔</author><pubDate>Fri, 07 Nov 2008 15:06:00 GMT</pubDate><guid>http://www.cppblog.com/woaidongmao/archive/2008/11/07/66256.html</guid><wfw:comment>http://www.cppblog.com/woaidongmao/comments/66256.html</wfw:comment><comments>http://www.cppblog.com/woaidongmao/archive/2008/11/07/66256.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/woaidongmao/comments/commentRss/66256.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/woaidongmao/services/trackbacks/66256.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 当要交换两个数的值时，通常的做法是定义一个临时变量，然后再进行交换。那么能不能不用临时变量而交换两个数的值呢？可以的！C语言提供的异或运算就可以实现这样的操作。  异或运算符^也称XOR运算符，它的规则是若参加运算的两个二进位同号，则结果为0（假）；异号为1（真）。即0 ^ 0 = 0, 0 ^ 1 = 1, 1 ^ 0 = 1, 1 ^ 1 = 0。&nbsp; 例：     #include ...&nbsp;&nbsp;<a href='http://www.cppblog.com/woaidongmao/archive/2008/11/07/66256.html'>阅读全文</a><img src ="http://www.cppblog.com/woaidongmao/aggbug/66256.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/woaidongmao/" target="_blank">肥仔</a> 2008-11-07 23:06 <a href="http://www.cppblog.com/woaidongmao/archive/2008/11/07/66256.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Class内部定义新的类型，并引伸出union的妙用</title><link>http://www.cppblog.com/woaidongmao/archive/2008/11/07/66255.html</link><dc:creator>肥仔</dc:creator><author>肥仔</author><pubDate>Fri, 07 Nov 2008 15:02:00 GMT</pubDate><guid>http://www.cppblog.com/woaidongmao/archive/2008/11/07/66255.html</guid><wfw:comment>http://www.cppblog.com/woaidongmao/comments/66255.html</wfw:comment><comments>http://www.cppblog.com/woaidongmao/archive/2008/11/07/66255.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/woaidongmao/comments/commentRss/66255.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/woaidongmao/services/trackbacks/66255.html</trackback:ping><description><![CDATA[<p class="MsoNormal"><span style="font-size: 12pt; font-family: 宋体; mso-bidi-font-family: arial">在类内部其实是可以定义一些类型的，比如<span lang="EN-US">struct</span>、<span lang="EN-US">union</span>、<span lang="EN-US">class</span>，其实也就只有这三类可以被定义，<span lang="EN-US"><?xml:namespace prefix = o /><o:p></o:p></span></span></p> <p class="MsoNormal"><span lang="EN-US" style="font-size: 12pt; font-family: 宋体; mso-bidi-font-family: arial"><o:p>&nbsp;</o:p></span></p> <p class="MsoNormal"><span style="font-size: 12pt; font-family: 宋体; mso-bidi-font-family: arial">也只有这三类可以定义它们各自的对象，然后“<span lang="EN-US">.</span>”出来或者“<span lang="EN-US">-&gt;</span>”出来，<span lang="EN-US">C++</span>中只有这三类了。<span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal"><span lang="EN-US" style="font-size: 12pt; font-family: 宋体; mso-bidi-font-family: arial"><o:p>&nbsp;</o:p></span></p> <p class="MsoNormal"><span style="font-size: 12pt; font-family: 宋体; mso-bidi-font-family: arial">对于它们各自来说，在一个类的内部都可以有三种方式来定义它们，比如对于<span lang="EN-US">union</span>，<span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal"><span style="font-size: 12pt; font-family: 宋体; mso-bidi-font-family: arial">第一种方式：<span lang="EN-US">//</span>定义了一个<span lang="EN-US">union</span>类型，并且定义了一个属于该类型的对象<span lang="EN-US">un</span>，因此<span lang="EN-US">sizeof(X)==4<o:p></o:p></span></span></p> <p class="MsoNormal"><span lang="EN-US" style="font-size: 12pt; font-family: 宋体; mso-bidi-font-family: arial">class X{<o:p></o:p></span></p> <p class="MsoNormal"><span lang="EN-US" style="font-size: 12pt; font-family: 宋体; mso-bidi-font-family: arial">public:<o:p></o:p></span></p> <p class="MsoNormal"><span lang="EN-US" style="font-size: 12pt; font-family: 宋体; mso-bidi-font-family: arial"><span style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp; </span>union UN{<o:p></o:p></span></p> <p class="MsoNormal"><span lang="EN-US" style="font-size: 12pt; font-family: 宋体; mso-bidi-font-family: arial"><span style="mso-tab-count: 2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>int m_nX;<o:p></o:p></span></p> <p class="MsoNormal"><span lang="EN-US" style="font-size: 12pt; font-family: 宋体; mso-bidi-font-family: arial"><span style="mso-tab-count: 2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>char* pchar;<o:p></o:p></span></p> <p class="MsoNormal"><span lang="EN-US" style="font-size: 12pt; font-family: 宋体; mso-bidi-font-family: arial"><span style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp; </span>}un;<o:p></o:p></span></p> <p class="MsoNormal"><span lang="EN-US" style="font-size: 12pt; font-family: 宋体; mso-bidi-font-family: arial">};<o:p></o:p></span></p> <p class="MsoNormal"><span style="font-size: 12pt; font-family: 宋体; mso-bidi-font-family: arial">第二种方式：<span lang="EN-US">//</span>定义了一个<span lang="EN-US">union</span>类型，但并没有定义属于该类型的任何对象，因此<span lang="EN-US">sizeof(X)==0<o:p></o:p></span></span></p> <p class="MsoNormal"><span lang="EN-US" style="font-size: 12pt; font-family: 宋体; mso-bidi-font-family: arial">class X{<o:p></o:p></span></p> <p class="MsoNormal"><span lang="EN-US" style="font-size: 12pt; font-family: 宋体; mso-bidi-font-family: arial">public:<o:p></o:p></span></p> <p class="MsoNormal"><span lang="EN-US" style="font-size: 12pt; font-family: 宋体; mso-bidi-font-family: arial"><span style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp; </span>union UN{<o:p></o:p></span></p> <p class="MsoNormal"><span lang="EN-US" style="font-size: 12pt; font-family: 宋体; mso-bidi-font-family: arial"><span style="mso-tab-count: 2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>int m_nX;<o:p></o:p></span></p> <p class="MsoNormal"><span lang="EN-US" style="font-size: 12pt; font-family: 宋体; mso-bidi-font-family: arial"><span style="mso-tab-count: 2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>char* pchar;<o:p></o:p></span></p> <p class="MsoNormal"><span lang="EN-US" style="font-size: 12pt; font-family: 宋体; mso-bidi-font-family: arial"><span style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp; </span>};<o:p></o:p></span></p> <p class="MsoNormal"><span lang="EN-US" style="font-size: 12pt; font-family: 宋体; mso-bidi-font-family: arial">};<o:p></o:p></span></p> <p class="MsoNormal"><span style="font-size: 12pt; font-family: 宋体; mso-bidi-font-family: arial">第三种方式：<span lang="EN-US">//</span>定义了一个匿名的<span lang="EN-US">union</span>类型，因此也就只能在<span lang="EN-US">X</span>内部使用了，并且此种情况隐含着已经<span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal"><span lang="EN-US" style="font-size: 12pt; font-family: 宋体; mso-bidi-font-family: arial"><o:p>&nbsp;</o:p></span></p> <p class="MsoNormal"><span style="font-size: 12pt; font-family: 宋体; mso-bidi-font-family: arial">在<span lang="EN-US">X</span>中定义了一个属于该匿名<span lang="EN-US">union</span>类型的对象，因此<span lang="EN-US">sizeof(X)==4</span>，并且此种情况最为特殊，可以直接<span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal"><span lang="EN-US" style="font-size: 12pt; font-family: 宋体; mso-bidi-font-family: arial"><o:p>&nbsp;</o:p></span></p> <p class="MsoNormal"><span style="font-size: 12pt; font-family: 宋体; mso-bidi-font-family: arial">通过类<span lang="EN-US">X</span>的对象来使用<span lang="EN-US">m_nX</span>和<span lang="EN-US">pchar</span>，例如<span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal"><span lang="EN-US" style="font-size: 12pt; font-family: 宋体; mso-bidi-font-family: arial">class X{<o:p></o:p></span></p> <p class="MsoNormal"><span lang="EN-US" style="font-size: 12pt; font-family: 宋体; mso-bidi-font-family: arial">public:<o:p></o:p></span></p> <p class="MsoNormal"><span lang="EN-US" style="font-size: 12pt; font-family: 宋体; mso-bidi-font-family: arial"><span style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp; </span>union {<o:p></o:p></span></p> <p class="MsoNormal"><span lang="EN-US" style="font-size: 12pt; font-family: 宋体; mso-bidi-font-family: arial"><span style="mso-tab-count: 2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>int m_nX;<o:p></o:p></span></p> <p class="MsoNormal"><span lang="EN-US" style="font-size: 12pt; font-family: 宋体; mso-bidi-font-family: arial"><span style="mso-tab-count: 2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>char* pchar;<o:p></o:p></span></p> <p class="MsoNormal"><span lang="EN-US" style="font-size: 12pt; font-family: 宋体; mso-bidi-font-family: arial"><span style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp; </span>};<o:p></o:p></span></p> <p class="MsoNormal"><span lang="EN-US" style="font-size: 12pt; font-family: 宋体; mso-bidi-font-family: arial">};<o:p></o:p></span></p> <p class="MsoNormal"><span lang="EN-US" style="font-size: 12pt; font-family: 宋体; mso-bidi-font-family: arial"><o:p>&nbsp;</o:p></span></p> <p class="MsoNormal"><span lang="EN-US" style="font-size: 12pt; font-family: 宋体; mso-bidi-font-family: arial">X x;<o:p></o:p></span></p> <p class="MsoNormal"><span lang="EN-US" style="font-size: 12pt; font-family: 宋体; mso-bidi-font-family: arial">x.m_nX=10;<o:p></o:p></span></p> <p class="MsoNormal"><span lang="EN-US" style="font-size: 12pt; font-family: 宋体; mso-bidi-font-family: arial">x.pchar="Hello World!";<o:p></o:p></span></p> <p class="MsoNormal"><span lang="EN-US" style="font-size: 12pt; font-family: 宋体; mso-bidi-font-family: arial"><o:p>&nbsp;</o:p></span></p> <p class="MsoNormal"><span style="font-size: 12pt; font-family: 宋体; mso-bidi-font-family: arial">对于前两种方式，都在类的内部定义了一个新的具有名字的型别，因此可以用这种新的类型来定义对应<span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal"><span lang="EN-US" style="font-size: 12pt; font-family: 宋体; mso-bidi-font-family: arial"><o:p>&nbsp;</o:p></span></p> <p class="MsoNormal"><span style="font-size: 12pt; font-family: 宋体; mso-bidi-font-family: arial">于该类型的对象，例如：<span lang="EN-US">X::UN myun;</span>但是这种定义是要求类内部的<span lang="EN-US">union</span>在定义时的修饰符为<span lang="EN-US">public</span>，<span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal"><span lang="EN-US" style="font-size: 12pt; font-family: 宋体; mso-bidi-font-family: arial"><o:p>&nbsp;</o:p></span></p> <p class="MsoNormal"><span style="font-size: 12pt; font-family: 宋体; mso-bidi-font-family: arial">否则就不能在类外部定义属于他们的对象，而只能在给类<span lang="EN-US">X</span>内部使用了。<span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal"><span lang="EN-US" style="font-size: 12pt; font-family: 宋体; mso-bidi-font-family: arial"><o:p>&nbsp;</o:p></span></p> <p class="MsoNormal"><span style="font-size: 12pt; font-family: 宋体; mso-bidi-font-family: arial">同理也可以知道在类内部通过<span lang="EN-US">typedef</span>定义出来的新型别也是如此。<span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal"><span lang="EN-US" style="font-size: 12pt; font-family: 宋体; mso-bidi-font-family: arial"><o:p>&nbsp;</o:p></span></p> <p class="MsoNormal"><span style="font-size: 12pt; font-family: 宋体; mso-bidi-font-family: arial">需要说明的是，<span lang="EN-US">union</span>用类里以第三种定义的方式出现的话，会有很奇妙的效果，非常奇妙，或许在今<span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal"><span lang="EN-US" style="font-size: 12pt; font-family: 宋体; mso-bidi-font-family: arial"><o:p>&nbsp;</o:p></span></p> <p class="MsoNormal"><span style="font-size: 12pt; font-family: 宋体; mso-bidi-font-family: arial">后的编程过程中可以加以利用。<span lang="EN-US">m_nX</span>和<span lang="EN-US">pchar</span>共享一块<span lang="EN-US">4</span>个字节的内存，只要不是同时需要<span lang="EN-US">m_nX</span>和<span lang="EN-US">pchar<o:p></o:p></span></span></p> <p class="MsoNormal"><span lang="EN-US" style="font-size: 12pt; font-family: 宋体; mso-bidi-font-family: arial"><o:p>&nbsp;</o:p></span></p> <p class="MsoNormal"><span style="font-size: 12pt; font-family: 宋体; mso-bidi-font-family: arial">出现的情况都可以只利用它们其中的一个，从而节省了内存开销。<span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal"><span lang="EN-US" style="font-size: 12pt; font-family: 宋体; mso-bidi-font-family: arial"><o:p>&nbsp;</o:p></span></p><img src ="http://www.cppblog.com/woaidongmao/aggbug/66255.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/woaidongmao/" target="_blank">肥仔</a> 2008-11-07 23:02 <a href="http://www.cppblog.com/woaidongmao/archive/2008/11/07/66255.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>