﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-那谁的技术博客-随笔分类-C\C++</title><link>http://www.cppblog.com/converse/category/803.html</link><description>感兴趣领域:高性能服务器编程,存储,算法,Linux内核</description><language>zh-cn</language><lastBuildDate>Tue, 06 Jul 2010 07:19:23 GMT</lastBuildDate><pubDate>Tue, 06 Jul 2010 07:19:23 GMT</pubDate><ttl>60</ttl><item><title>C++的流设计很糟糕</title><link>http://www.cppblog.com/converse/archive/2010/07/06/119427.html</link><dc:creator>那谁</dc:creator><author>那谁</author><pubDate>Tue, 06 Jul 2010 05:04:00 GMT</pubDate><guid>http://www.cppblog.com/converse/archive/2010/07/06/119427.html</guid><wfw:comment>http://www.cppblog.com/converse/comments/119427.html</wfw:comment><comments>http://www.cppblog.com/converse/archive/2010/07/06/119427.html#Feedback</comments><slash:comments>14</slash:comments><wfw:commentRss>http://www.cppblog.com/converse/comments/commentRss/119427.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/converse/services/trackbacks/119427.html</trackback:ping><description><![CDATA[最近需要提供一个功能,采用类似C++流输出的格式输出一些日志信息, 例如Log(FATAL) &lt;&lt; "log to" .<br><br>我找了两个类似项目来研究,google的<a href="http://code.google.com/p/google-glog/">glog</a> 和 <a href="http://log4cpp.sourceforge.net/">log4cpp</a>, 它们都支持以C++流输出格式进行输出.<br><br>但是研究到最后,我发现最大的问题是, 如果按照C++的流输出格式进行输出, 将无法判定需要输出的信息到哪里是结束.比如log &lt;&lt; "hello " &lt;&lt; "world",是无法判断到底在输出"hello"还是"world"的时候上面的参数输入已经结束了.上面两个项目中, 解决这个问题的办法大致是相同的,以下面可编译运行代码为例说明它们的做法(在linux g++下面编译通过):<br>
<div style="background-color: #eeeeee; font-size: 13px; border: 1px solid #cccccc; padding: 4px 5px 4px 4px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #000000;">#include&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">iostream</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br>#include&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">sstream</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br><br>#ifdef&nbsp;__DEPRECATED<br></span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;Make&nbsp;GCC&nbsp;quiet.</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;#&nbsp;undef&nbsp;__DEPRECATED<br>&nbsp;#&nbsp;include&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">strstream</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br>&nbsp;#&nbsp;define&nbsp;__DEPRECATED<br></span><span style="color: #0000ff;">#else</span><span style="color: #000000;"><br>&nbsp;#&nbsp;include&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">strstream</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br></span><span style="color: #0000ff;">#endif</span><span style="color: #000000;"><br><br></span><span style="color: #0000ff;">using</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">namespace</span><span style="color: #000000;">&nbsp;std;<br><br></span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;LoggerStream&nbsp;:&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;std::ostrstream&nbsp;{<br>&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">:<br>&nbsp;&nbsp;LoggerStream(</span><span style="color: #0000ff;">char</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;buf,&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;len)<br>&nbsp;&nbsp;&nbsp;:&nbsp;ostrstream(buf,&nbsp;len),<br>&nbsp;&nbsp;&nbsp;&nbsp;buf_(buf),<br>&nbsp;&nbsp;&nbsp;&nbsp;len_(len)&nbsp;{<br>&nbsp;&nbsp;}<br><br>&nbsp;&nbsp;</span><span style="color: #000000;">~</span><span style="color: #000000;">LoggerStream()&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;do&nbsp;the&nbsp;real&nbsp;fucking&nbsp;output</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;cout&nbsp;</span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;">&nbsp;buf_;<br>&nbsp;&nbsp;}<br><br>&nbsp;</span><span style="color: #0000ff;">private</span><span style="color: #000000;">:<br>&nbsp;&nbsp;</span><span style="color: #0000ff;">char</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">buf_;<br>&nbsp;&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;len_;<br>};<br><br></span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;main()&nbsp;{<br>&nbsp;&nbsp;</span><span style="color: #0000ff;">char</span><span style="color: #000000;">&nbsp;buf[</span><span style="color: #000000;">100</span><span style="color: #000000;">]&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;{</span><span style="color: #000000;">'</span><span style="color: #000000;">\0</span><span style="color: #000000;">'</span><span style="color: #000000;">};<br><br>&nbsp;&nbsp;LoggerStream(buf,&nbsp;</span><span style="color: #0000ff;">sizeof</span><span style="color: #000000;">(buf))&nbsp;</span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">1</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">&nbsp;hello&nbsp;world\n</span><span style="color: #000000;">"</span><span style="color: #000000;">;<br><br>&nbsp;&nbsp;cout&nbsp;</span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">buf&nbsp;=&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;">&nbsp;buf&nbsp;</span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;">&nbsp;endl;<br><br>&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">;<br>}<br></span></div>
<br>在上面的代码中, 开始进行输出的时候首先初始化一个LoggerStream对象, 而在输出参数输入完毕的时候将调用它的析构函数,在这个析构函数中才完成真正的输出动作.也就是说,由于对输入参数结束位置判断手段的缺失,C++中不得不采用这个手段在析构函数中完成最终的输出工作.<br>这样的做法,最大的问题是,频繁的构造/析构开销大,而且每个"&lt;&lt;"操作符背后又需要调用ostream的operator&lt;&lt;,也就是假如你的输入参数有三个将调用operator &lt;&lt;三次(当然是经过重载的,不一定都是同一个operator&lt;&lt;),因此,假如需要考虑多线程的话,那么一次输入有多个函数函数中被调用,仍然是问题.天,要使用这门语言写出正确的程序来,需要了解底下多少的细节呢?!<br><br>最后,我向项目组反映这个问题,一致同意以C中类似sprintf可变参数的形式实现这个功能.可变参数解决这个问题,就我的感觉而言,就是输入参数的时候,稍显复杂,需要用户指定输入的格式.然而,其实这个做法也有好处:作为函数的使用者,你必须明确的知道你在做什么并且反馈给你所使用的函数.明确的,无歧义的使用函数,而不是依靠所谓函数重载猜你的用意,我想也是避免问题的一个手段.gcc中, 提供了对可变参数检查的机制,见<a href="http://unixwiz.net/techtips/gnu-c-attributes.html">这里</a>.<br><br>   <img src ="http://www.cppblog.com/converse/aggbug/119427.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/converse/" target="_blank">那谁</a> 2010-07-06 13:04 <a href="http://www.cppblog.com/converse/archive/2010/07/06/119427.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>解读google C++ code style谈对C++的理解</title><link>http://www.cppblog.com/converse/archive/2010/05/29/116689.html</link><dc:creator>那谁</dc:creator><author>那谁</author><pubDate>Sat, 29 May 2010 12:34:00 GMT</pubDate><guid>http://www.cppblog.com/converse/archive/2010/05/29/116689.html</guid><wfw:comment>http://www.cppblog.com/converse/comments/116689.html</wfw:comment><comments>http://www.cppblog.com/converse/archive/2010/05/29/116689.html#Feedback</comments><slash:comments>30</slash:comments><wfw:commentRss>http://www.cppblog.com/converse/comments/commentRss/116689.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/converse/services/trackbacks/116689.html</trackback:ping><description><![CDATA[
C++是一门足够复杂的语言.说它"足够复杂",是因为C++提供了足够多编程范式--泛型, 模板, 面向对象, 异常,等等.顺便说说,我已经很久没有跟进C++的最新发展了(比如C++0x), 所以前面列举出来的特性应该只是C++所有特性的一个部分罢了.C++特性过多很难驾驭好C++的原因之一.另一个原因是C++过于"自作聪明",在很多地方悄无声息的做了很多事情, 比如隐式的类型转换, 重载, 模板推导等等.而很多时候,这些动作难以察觉,有时候会在你意想不到的地方发生,即使是熟练的C++程序员也难免被误伤.(关于了解C++编译器自作聪明做了哪些事情, &lt;&lt;深入理解C++物件模型&gt;&gt;是不错的选择).<br><br>世界上有很多问题, 人们知道如何去解决.但是, 似乎这还不算是最高明的,更高明的做法是学会避免问题的发生.而如何避免问题的发生, 需要经验的积累--曾经犯下错误,吃一堑长一智,于是知道哪些事情是不该做的或者是不应该这么做的.<br><br><a href="http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml">google C++ code style</a>是google对外公布的一份google内部编写C++的代码规范文档.与其他很多我曾经看过的编码文档一样,里面有一些关于代码风格的规定,也就是代码的外观,这一部分不在这里过多讨论,毕竟代码如何才叫"美观"是一个见仁见智的话题.在这里专门讨论这份文档中对一些C++特性该如何使用的讨论,最后再做一个总结.注意其中的序号并不是文档中的序号,如果要详细了解,可以自己去看这份文档.<br><br><div style="background-color: rgb(238, 238, 238); font-size: 13px; border-left-color: rgb(204, 204, 204); padding-right: 5px; padding-bottom: 4px; padding-left: 4px; padding-top: 4px; width: 98%; word-break: break-all; "><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #000000; ">1</span><span style="color: #000000; ">)&nbsp;Static&nbsp;and&nbsp;Global&nbsp;Variables<br>&nbsp;&nbsp;&nbsp;Static&nbsp;or&nbsp;global&nbsp;variables&nbsp;of&nbsp;</span><span style="color: #0000FF; ">class</span><span style="color: #000000; ">&nbsp;type&nbsp;are&nbsp;forbidden:&nbsp;they&nbsp;cause&nbsp;hard</span><span style="color: #000000; ">-</span><span style="color: #000000; ">to</span><span style="color: #000000; ">-</span><span style="color: #000000; ">find&nbsp;bugs&nbsp;due&nbsp;to&nbsp;indeterminate&nbsp;order&nbsp;of&nbsp;construction&nbsp;and&nbsp;destruction.</span></div>google明确禁止全局对象是类对象, 只能是所谓POD(Plain Old Data,如int char等)数据才行.因为C++标准中没有明确规定全局对象的初始化顺序, 假设全局类对象A,B,其中A的初始化依赖于B的值, 那么将无法保证最后的结果.如果非要使用全局类对象, 那么只能使用指针, 在main等函数入口统一进行初始化.<br><br><div style="background-color: rgb(238, 238, 238); font-size: 13px; border-left-color: rgb(204, 204, 204); padding-right: 5px; padding-bottom: 4px; padding-left: 4px; padding-top: 4px; width: 98%; word-break: break-all; "><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #000000; ">2</span><span style="color: #000000; ">)&nbsp;Doing&nbsp;Work&nbsp;</span><span style="color: #0000FF; ">in</span><span style="color: #000000; ">&nbsp;Constructors<br>In&nbsp;general,&nbsp;constructors&nbsp;should&nbsp;merely&nbsp;</span><span style="color: #0000FF; ">set</span><span style="color: #000000; ">&nbsp;member&nbsp;variables&nbsp;to&nbsp;their&nbsp;initial&nbsp;values.&nbsp;Any&nbsp;complex&nbsp;initialization&nbsp;should&nbsp;go&nbsp;</span><span style="color: #0000FF; ">in</span><span style="color: #000000; ">&nbsp;an&nbsp;</span><span style="color: #0000FF; ">explicit</span><span style="color: #000000; ">&nbsp;Init()&nbsp;method.&nbsp;</span></div>文档规定, 在类构造函数中对类成员对象做基本的初始化操作, 所有的复杂初始化操作集中一个比如Init()的函数中,理由如下:<br>
<ul>
    <li> There is no easy way for constructors to signal errors,
    short of using exceptions (which are
    <a href="http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Exceptions">forbidden</a>).
    </li>
    <li> If the work fails, we now have an object whose
    initialization code failed, so it may be an
    indeterminate state.
    </li>
    <li> If the work calls virtual functions, these calls will
    not get dispatched to the subclass implementations.
    Future modification to your class can quietly introduce
    this problem even if your class is not currently
    subclassed, causing much confusion.
    </li>
    <li> If someone creates a global variable of this type
    (which is against the rules, but still), the
    constructor code will be called before
    <code>main()</code>, possibly breaking some implicit
    assumptions in the constructor code.  For instance,
    <a href="http://google-gflags.googlecode.com/">gflags</a>
    will not yet have been initialized.
    </li>
</ul>
简单的概括起来也就是:构造函数没有返回值, 难以让使用者感知错误;假如在构造函数中调用虚拟函数, 则无法按照使用者的想法调用到对应子类中实现的虚拟函数(理由是构造函数还未完成意味着这个对象还没有被成功构造完成).<br><br><div style="background-color: rgb(238, 238, 238); font-size: 13px; border-left-color: rgb(204, 204, 204); padding-right: 5px; padding-bottom: 4px; padding-left: 4px; padding-top: 4px; width: 98%; word-break: break-all; "><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #000000; ">3</span><span style="color: #000000; ">)&nbsp;Default&nbsp;Constructors<br>You&nbsp;must&nbsp;define&nbsp;a&nbsp;</span><span style="color: #0000FF; ">default</span><span style="color: #000000; ">&nbsp;constructor&nbsp;</span><span style="color: #0000FF; ">if</span><span style="color: #000000; ">&nbsp;your&nbsp;</span><span style="color: #0000FF; ">class</span><span style="color: #000000; ">&nbsp;defines&nbsp;member&nbsp;variables&nbsp;and&nbsp;has&nbsp;no&nbsp;other&nbsp;constructors.&nbsp;Otherwise&nbsp;the&nbsp;compiler&nbsp;will&nbsp;</span><span style="color: #0000FF; ">do</span><span style="color: #000000; ">&nbsp;it&nbsp;</span><span style="color: #0000FF; ">for</span><span style="color: #000000; ">&nbsp;you,&nbsp;badly.&nbsp;</span></div>当程序员没有为类编写一个默认构造函数的时候, 编译器会自动生成一个默认构造函数,而这个编译器生成的函数如何实现(比如如何初始化类成员对象)是不确定的.这样,假如出现问题时将给调试跟踪带来困难.所以, 规范要求每个类都需要编写一个默认构造函数避免这种情况的出现.<br><br><div style="background-color: rgb(238, 238, 238); font-size: 13px; border-left-color: rgb(204, 204, 204); padding-right: 5px; padding-bottom: 4px; padding-left: 4px; padding-top: 4px; width: 98%; word-break: break-all; "><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #000000; ">4</span><span style="color: #000000; ">)&nbsp;Explicit&nbsp;Constructors<br>Use&nbsp;the&nbsp;C</span><span style="color: #000000; ">++</span><span style="color: #000000; ">&nbsp;keyword&nbsp;</span><span style="color: #0000FF; ">explicit</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">for</span><span style="color: #000000; ">&nbsp;constructors&nbsp;with&nbsp;one&nbsp;argument.</span></div>假如构造函数只有一个参数, 使用explicit避免隐式转换,
因为隐式转换可能在你并不需要的时候出现.<br>
<br><div style="background-color: rgb(238, 238, 238); font-size: 13px; border-left-color: rgb(204, 204, 204); padding-right: 5px; padding-bottom: 4px; padding-left: 4px; padding-top: 4px; width: 98%; word-break: break-all; "><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #000000; ">5</span><span style="color: #000000; ">)&nbsp;Copy&nbsp;Constructors<br>Provide&nbsp;a&nbsp;copy&nbsp;constructor&nbsp;and&nbsp;assignment&nbsp;</span><span style="color: #0000FF; ">operator</span><span style="color: #000000; ">&nbsp;only&nbsp;when&nbsp;necessary.&nbsp;Otherwise,&nbsp;disable&nbsp;them&nbsp;with&nbsp;DISALLOW_COPY_AND_ASSIGN.</span></div>只有当必要的时候才需要定义拷贝构造函数和赋值操作符.
同上一条理由一样, 避免一些隐式的转换.另一条理由是,"="难以跟踪,如果真的要实现类似的功能,可以提供比如名为Copy()的函数,这样子一目了然,不会像赋值操作符那样可能在每个"="出现的地方出现.<br><br><div style="background-color: rgb(238, 238, 238); font-size: 13px; border-left-color: rgb(204, 204, 204); padding-right: 5px; padding-bottom: 4px; padding-left: 4px; padding-top: 4px; width: 98%; word-break: break-all; "><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #000000; ">6</span><span style="color: #000000; ">)&nbsp;Operator&nbsp;Overloading<br>Do&nbsp;not&nbsp;overload&nbsp;operators&nbsp;except&nbsp;</span><span style="color: #0000FF; ">in</span><span style="color: #000000; ">&nbsp;rare,&nbsp;special&nbsp;circumstances.</span></div>不要重载操作符.同样, 也是避免莫名其妙的调用了一些函数.同上一条一样, 比如要提供对"=="的重载, 可以提供一个名为Equal()的函数, 如果需要提供对"+"的重载, 可以提供一个名为Add()的函数.<br><br><div style="background-color: rgb(238, 238, 238); font-size: 13px; border-left-color: rgb(204, 204, 204); padding-right: 5px; padding-bottom: 4px; padding-left: 4px; padding-top: 4px; width: 98%; word-break: break-all; "><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #000000; ">7</span><span style="color: #000000; ">)&nbsp;Function&nbsp;Overloading<br>Use&nbsp;overloaded&nbsp;functions&nbsp;(including&nbsp;constructors)&nbsp;only&nbsp;</span><span style="color: #0000FF; ">in</span><span style="color: #000000; ">&nbsp;cases&nbsp;where&nbsp;input&nbsp;can&nbsp;be&nbsp;specified&nbsp;</span><span style="color: #0000FF; ">in</span><span style="color: #000000; ">&nbsp;different&nbsp;types&nbsp;that&nbsp;contain&nbsp;the&nbsp;same&nbsp;information.&nbsp;Do&nbsp;not&nbsp;use&nbsp;function&nbsp;overloading&nbsp;to&nbsp;simulate&nbsp;</span><span style="color: #0000FF; ">default</span><span style="color: #000000; ">&nbsp;function&nbsp;parameters.</span></div>只有在不同的类型表示同样的信息的时候, 可以使用重载函数.其他情况下,一律不能使用.使用重载, 也可能出现一些隐式出现的转换.所以, 在需要对不同函数进行同样操作的时候, 可以在函数名称上进行区分, 而不是使用重载,如可以提供针对string类型的AppendString()函数, 针对int类型的AppendInt()函数,而不是对string和int类型重载Append()函数.另一个好处在于, 在阅读代码时,通过函数名称可以一目了然.<br><br><div style="background-color: rgb(238, 238, 238); font-size: 13px; border-left-color: rgb(204, 204, 204); padding-right: 5px; padding-bottom: 4px; padding-left: 4px; padding-top: 4px; width: 98%; word-break: break-all; "><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #000000; ">8</span><span style="color: #000000; ">)&nbsp;Exceptions<br>We&nbsp;</span><span style="color: #0000FF; ">do</span><span style="color: #000000; ">&nbsp;not&nbsp;use&nbsp;C</span><span style="color: #000000; ">++</span><span style="color: #000000; ">&nbsp;exceptions.</span></div>不使用异常.理由如下:<br>
<ul>
    <li>When you add a <code>throw</code> statement to an existing
    function, you must examine all of its transitive callers.
    Either
    they must make at least the basic exception safety guarantee,
    or
    they must never catch the exception and be happy with the
    program terminating as a result. For instance, if
    <code>f()</code> calls <code>g()</code> calls
    <code>h()</code>, and <code>h</code> throws an exception
    that <code>f</code> catches, <code>g</code> has to be
    careful or it may not clean up properly.</li>
    <li>More generally, exceptions make the control flow of
    programs difficult to evaluate by looking at code: functions
    may return in places you don't expect. This results
    maintainability and debugging difficulties. You can minimize
    this cost via some rules on how and where exceptions can be
    used, but at the cost of more that a developer needs to know
    and understand.</li>
    <li>Exception safety requires both RAII and different coding
    practices. Lots of supporting machinery is needed to make
    writing correct exception-safe code easy. Further, to avoid
    requiring readers to understand the entire call graph,
    exception-safe code must isolate logic that writes to
    persistent state into a "commit" phase. This will have both
    benefits and costs (perhaps where you're forced to obfuscate
    code to isolate the commit). Allowing exceptions would force
    us to always pay those costs even when they're not worth
    it.</li>
    <li>Turning on exceptions adds data to each binary produced,
    increasing compile time (probably slightly) and possibly
    increasing address space pressure.
    </li>
    <li>The availability of exceptions may encourage developers
    to throw them when they are not appropriate or recover from
    them when it's not safe to do so. For example, invalid user
    input should not cause exceptions to be thrown. We would
    need to make the style guide even longer to document these
    restrictions!</li>
</ul>
上面提到的理由中, 我认为使用异常最大的害处就是:异常的使用导致了程序无法按照代码所展现的流程去走的, 比如代码里面写了步骤一二三,但是假如有异常出现, 这就不好预知代码真正步进的步骤了, 在出现问题时, 给调试和跟踪带来困难.<br>另外, 我更喜欢unix API的设计.熟悉unix编程的人都知道, unix API基本上都遵守下列规则:<br>a) 返回0表示成功, 其他(一般是-1)表示失败.<br>b) 在失败时, 可以根据errno判断失败的原因, 这些在man手册中都是会清楚的描述.<br><br>总结一下, 这份规范中规避的C++特性大致分为以下几类:<br>a) 避免使用那些没有确定行为的特性:如全局变量不能是类对象(初始化顺序不确定), 不使用编译器生成的默认构造函数(构造行为不确定), 异常(代码走向不确定).<br>b) 避免使用那些隐式发生的操作:如声明单参数构造函数为explict以避免隐式转换, 不定义拷贝构造函数避免隐式的拷贝行为, 不使用操作符重载避免隐式的转换<br>c) 对模棱两可的特性给予明确的规定:不使用函数重载而是定义对每个类型明确的函数.<br>d) 即使出错了程序也有办法知道: 比如不能在类构造函数中进行复杂的构造操作, 将这些移动到类Init()的函数中.<br><br>同时, 这份文档中描述的大部分C++特性, 都是我之前所熟悉的(除了RTTI之外, 不过这里提到它也是要说明不使用它,另外还提到boost, 不过也是说的要对它"有限制"的使用,比如里面的智能指针).可以看到, 面对这样一门复杂同时还在不停的发展更新特性的语言, google的态度是比较"保守"的.这与我之前对C++的理解也是接近的, 我一直认为C++中需要使用到的特性有基本的面向对象+STL就够了(经过最近的编码实践,我认为还得加个智能指针).我对这个"保守"态度的理解是, 以C++当前的应用场景来看, 这些特性已经足够, 如果使用其他一些更加复杂的, 对人的要求提高了, 代码的可读性以及以后的可维护性就下降了.<br><br>前面说过, 避免问题的出现比解决问题来的更加高明些, 而面对C++这一个提供了众多特性, google C++ code style给予了明确的规定, 也就是每个行为, 如果都能做到有明确的动作, 同时结果也都是可以预知的, 那么会将出问题的概率最大可能的降低, 即使出了问题, 也容易跟踪.<br><br>上面描述的并不是这份文档中有关C++的所有内容, 只不过我觉得这些更加有同感些, 详细的内容, 可以参看这份文档.都知道google的作品,质量有保证, 除了人的素质确实高之外, 有规范的制度保证也是重要的原因, 毕竟只要是人就会犯错, 为了最大限度的避免人犯错, 有一份详尽的代码规范, 写好哪些该做哪些不该做哪些不该这么做, 也是制度上的保证.另外, 假如每个人都能以一个比较高的标准要求自己所写的代码, 久而久之, 获得进步也是必然的结果.<br><br>从这套规范里面, 我的另一个感悟是, 不论是什么行业, "学会如何正确的做事情", 都是十分必要的.这个"正确的做事情", 具体到编码来说, 就是代码规范里面提到的那些要求.而除去编码, 做任何的事情, 使用正确的方式做事, 都是尽可能少的避免错误的方法.但是, "错"与"对"是相对而言的, 没有之前"错"的经历, 就不好体会什么叫"对".所以, "如何正确的做事", 说到了最后, 还得看个人的经验积累, 有了之前"错误"的经历,才能吃一堑长一智, "错误"并不是一无是处的, 只不过, 并不是谁都去尝试着从中学习.<br><br><br>        <img src ="http://www.cppblog.com/converse/aggbug/116689.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/converse/" target="_blank">那谁</a> 2010-05-29 20:34 <a href="http://www.cppblog.com/converse/archive/2010/05/29/116689.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Callback在C\C++中的实现</title><link>http://www.cppblog.com/converse/archive/2010/04/19/113023.html</link><dc:creator>那谁</dc:creator><author>那谁</author><pubDate>Mon, 19 Apr 2010 14:45:00 GMT</pubDate><guid>http://www.cppblog.com/converse/archive/2010/04/19/113023.html</guid><wfw:comment>http://www.cppblog.com/converse/comments/113023.html</wfw:comment><comments>http://www.cppblog.com/converse/archive/2010/04/19/113023.html#Feedback</comments><slash:comments>8</slash:comments><wfw:commentRss>http://www.cppblog.com/converse/comments/commentRss/113023.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/converse/services/trackbacks/113023.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: Callback是这样的一类对象(在这里不能简单的理解为"回调函数"了):你注册一个函数,以及调用它时的参数,希望在满足某个条件时,以这些注册的函数调用这个回调,完成指定的操作.很多地方会使用到这个概念.比如,UI程序中,注册一个函数,当某个鼠标事件发生的时候自动调用;比如,创建一个线程,线程开始运行时,执行注册的函数操作.Callback的出现,本质上是因为很多操作都有异步化的需要---你不知道...&nbsp;&nbsp;<a href='http://www.cppblog.com/converse/archive/2010/04/19/113023.html'>阅读全文</a><img src ="http://www.cppblog.com/converse/aggbug/113023.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/converse/" target="_blank">那谁</a> 2010-04-19 22:45 <a href="http://www.cppblog.com/converse/archive/2010/04/19/113023.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>自己实现的memcpy</title><link>http://www.cppblog.com/converse/archive/2009/04/18/80316.html</link><dc:creator>那谁</dc:creator><author>那谁</author><pubDate>Sat, 18 Apr 2009 01:30:00 GMT</pubDate><guid>http://www.cppblog.com/converse/archive/2009/04/18/80316.html</guid><wfw:comment>http://www.cppblog.com/converse/comments/80316.html</wfw:comment><comments>http://www.cppblog.com/converse/archive/2009/04/18/80316.html#Feedback</comments><slash:comments>12</slash:comments><wfw:commentRss>http://www.cppblog.com/converse/comments/commentRss/80316.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/converse/services/trackbacks/80316.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 没有考虑目标和源地址可能重复的情况,不知道除了这个方法之外不用汇编等方式还有没有更快的方法?至少我目前是想不出来:)<br>&nbsp;&nbsp;<a href='http://www.cppblog.com/converse/archive/2009/04/18/80316.html'>阅读全文</a><img src ="http://www.cppblog.com/converse/aggbug/80316.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/converse/" target="_blank">那谁</a> 2009-04-18 09:30 <a href="http://www.cppblog.com/converse/archive/2009/04/18/80316.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>服务器公共库开发--线程安全的singleton类, 可配置的线程锁管理类 </title><link>http://www.cppblog.com/converse/archive/2008/08/01/57798.html</link><dc:creator>那谁</dc:creator><author>那谁</author><pubDate>Fri, 01 Aug 2008 15:32:00 GMT</pubDate><guid>http://www.cppblog.com/converse/archive/2008/08/01/57798.html</guid><wfw:comment>http://www.cppblog.com/converse/comments/57798.html</wfw:comment><comments>http://www.cppblog.com/converse/archive/2008/08/01/57798.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/converse/comments/commentRss/57798.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/converse/services/trackbacks/57798.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &nbsp;&nbsp;<a href='http://www.cppblog.com/converse/archive/2008/08/01/57798.html'>阅读全文</a><img src ="http://www.cppblog.com/converse/aggbug/57798.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/converse/" target="_blank">那谁</a> 2008-08-01 23:32 <a href="http://www.cppblog.com/converse/archive/2008/08/01/57798.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>服务器公共库开发--读取ini文件格式的类</title><link>http://www.cppblog.com/converse/archive/2008/07/29/57383.html</link><dc:creator>那谁</dc:creator><author>那谁</author><pubDate>Mon, 28 Jul 2008 16:57:00 GMT</pubDate><guid>http://www.cppblog.com/converse/archive/2008/07/29/57383.html</guid><wfw:comment>http://www.cppblog.com/converse/comments/57383.html</wfw:comment><comments>http://www.cppblog.com/converse/archive/2008/07/29/57383.html#Feedback</comments><slash:comments>7</slash:comments><wfw:commentRss>http://www.cppblog.com/converse/comments/commentRss/57383.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/converse/services/trackbacks/57383.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &nbsp;&nbsp;<a href='http://www.cppblog.com/converse/archive/2008/07/29/57383.html'>阅读全文</a><img src ="http://www.cppblog.com/converse/aggbug/57383.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/converse/" target="_blank">那谁</a> 2008-07-29 00:57 <a href="http://www.cppblog.com/converse/archive/2008/07/29/57383.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>如何使用位操作得到大于N且为2的次方的最小的数</title><link>http://www.cppblog.com/converse/archive/2008/06/21/54225.html</link><dc:creator>那谁</dc:creator><author>那谁</author><pubDate>Sat, 21 Jun 2008 07:36:00 GMT</pubDate><guid>http://www.cppblog.com/converse/archive/2008/06/21/54225.html</guid><wfw:comment>http://www.cppblog.com/converse/comments/54225.html</wfw:comment><comments>http://www.cppblog.com/converse/archive/2008/06/21/54225.html#Feedback</comments><slash:comments>8</slash:comments><wfw:commentRss>http://www.cppblog.com/converse/comments/commentRss/54225.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/converse/services/trackbacks/54225.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 如何使用位操作得到大于N且为2的次方的最小的数&nbsp;&nbsp;<a href='http://www.cppblog.com/converse/archive/2008/06/21/54225.html'>阅读全文</a><img src ="http://www.cppblog.com/converse/aggbug/54225.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/converse/" target="_blank">那谁</a> 2008-06-21 15:36 <a href="http://www.cppblog.com/converse/archive/2008/06/21/54225.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>(C++)一个愚蠢的错误</title><link>http://www.cppblog.com/converse/archive/2008/06/06/52390.html</link><dc:creator>那谁</dc:creator><author>那谁</author><pubDate>Fri, 06 Jun 2008 13:30:00 GMT</pubDate><guid>http://www.cppblog.com/converse/archive/2008/06/06/52390.html</guid><wfw:comment>http://www.cppblog.com/converse/comments/52390.html</wfw:comment><comments>http://www.cppblog.com/converse/archive/2008/06/06/52390.html#Feedback</comments><slash:comments>22</slash:comments><wfw:commentRss>http://www.cppblog.com/converse/comments/commentRss/52390.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/converse/services/trackbacks/52390.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: (C++)一个愚蠢的错误&nbsp;&nbsp;<a href='http://www.cppblog.com/converse/archive/2008/06/06/52390.html'>阅读全文</a><img src ="http://www.cppblog.com/converse/aggbug/52390.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/converse/" target="_blank">那谁</a> 2008-06-06 21:30 <a href="http://www.cppblog.com/converse/archive/2008/06/06/52390.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>研究了一下SGI STL的内存算法</title><link>http://www.cppblog.com/converse/archive/2008/04/01/45947.html</link><dc:creator>那谁</dc:creator><author>那谁</author><pubDate>Tue, 01 Apr 2008 11:55:00 GMT</pubDate><guid>http://www.cppblog.com/converse/archive/2008/04/01/45947.html</guid><wfw:comment>http://www.cppblog.com/converse/comments/45947.html</wfw:comment><comments>http://www.cppblog.com/converse/archive/2008/04/01/45947.html#Feedback</comments><slash:comments>6</slash:comments><wfw:commentRss>http://www.cppblog.com/converse/comments/commentRss/45947.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/converse/services/trackbacks/45947.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 仿SGI STL的内存池算法.<br>&nbsp;&nbsp;<a href='http://www.cppblog.com/converse/archive/2008/04/01/45947.html'>阅读全文</a><img src ="http://www.cppblog.com/converse/aggbug/45947.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/converse/" target="_blank">那谁</a> 2008-04-01 19:55 <a href="http://www.cppblog.com/converse/archive/2008/04/01/45947.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>memcache内存池的设计原理</title><link>http://www.cppblog.com/converse/archive/2008/01/21/41592.html</link><dc:creator>那谁</dc:creator><author>那谁</author><pubDate>Mon, 21 Jan 2008 15:34:00 GMT</pubDate><guid>http://www.cppblog.com/converse/archive/2008/01/21/41592.html</guid><wfw:comment>http://www.cppblog.com/converse/comments/41592.html</wfw:comment><comments>http://www.cppblog.com/converse/archive/2008/01/21/41592.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/converse/comments/commentRss/41592.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/converse/services/trackbacks/41592.html</trackback:ping><description><![CDATA[memcache中管理内存的数据结构如下:<br><br>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #000000">typedef&nbsp;struct&nbsp;{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;size;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">/*</span><span style="COLOR: #000000">&nbsp;sizes&nbsp;of&nbsp;items&nbsp;</span><span style="COLOR: #000000">*/</span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;perslab;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">/*</span><span style="COLOR: #000000">&nbsp;how&nbsp;many&nbsp;items&nbsp;per&nbsp;slab&nbsp;</span><span style="COLOR: #000000">*/</span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;void&nbsp;</span><span style="COLOR: #000000">**</span><span style="COLOR: #000000">slots;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">/*</span><span style="COLOR: #000000">&nbsp;list&nbsp;of&nbsp;item&nbsp;ptrs&nbsp;</span><span style="COLOR: #000000">*/</span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;sl_total;&nbsp;&nbsp;</span><span style="COLOR: #000000">/*</span><span style="COLOR: #000000">&nbsp;size&nbsp;of&nbsp;previous&nbsp;</span><span style="COLOR: #0000ff">array</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">*/</span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;sl_curr;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">/*</span><span style="COLOR: #000000">&nbsp;first&nbsp;free&nbsp;slot&nbsp;</span><span style="COLOR: #000000">*/</span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;void&nbsp;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">end_page_ptr;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">/*</span><span style="COLOR: #000000">&nbsp;pointer&nbsp;</span><span style="COLOR: #0000ff">to</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">next</span><span style="COLOR: #000000">&nbsp;free&nbsp;item&nbsp;at&nbsp;</span><span style="COLOR: #0000ff">end</span><span style="COLOR: #000000">&nbsp;of&nbsp;page,&nbsp;</span><span style="COLOR: #0000ff">or</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">*/</span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;end_page_free;&nbsp;</span><span style="COLOR: #000000">/*</span><span style="COLOR: #000000">&nbsp;number&nbsp;of&nbsp;items&nbsp;remaining&nbsp;at&nbsp;</span><span style="COLOR: #0000ff">end</span><span style="COLOR: #000000">&nbsp;of&nbsp;last&nbsp;alloced&nbsp;page&nbsp;</span><span style="COLOR: #000000">*/</span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;slabs;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">/*</span><span style="COLOR: #000000">&nbsp;how&nbsp;many&nbsp;slabs&nbsp;were&nbsp;allocated&nbsp;</span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000">&nbsp;this&nbsp;class&nbsp;</span><span style="COLOR: #000000">*/</span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;void&nbsp;</span><span style="COLOR: #000000">**</span><span style="COLOR: #000000">slab_list;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">/*</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">array</span><span style="COLOR: #000000">&nbsp;of&nbsp;slab&nbsp;pointers&nbsp;</span><span style="COLOR: #000000">*/</span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;list_size;&nbsp;</span><span style="COLOR: #000000">/*</span><span style="COLOR: #000000">&nbsp;size&nbsp;of&nbsp;prev&nbsp;</span><span style="COLOR: #0000ff">array</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">*/</span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;killing;&nbsp;&nbsp;</span><span style="COLOR: #000000">/*</span><span style="COLOR: #000000">&nbsp;index</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">&nbsp;of&nbsp;dying&nbsp;slab,&nbsp;</span><span style="COLOR: #0000ff">or</span><span style="COLOR: #000000">&nbsp;zero&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">&nbsp;none&nbsp;</span><span style="COLOR: #000000">*/</span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>}&nbsp;slabclass_t;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span></div>
<br>程序中有一个全局的数组<br>static slabclass_t slabclass[POWER_LARGEST + 1]用于保存slab,预分配内存池时调用的是void slabs_init(const size_t limit, const double factor) 函数,其中limit是内存池的最大容量,factor是分配时的增长因子.<br>比方说,加入factor是2,第一个在slabclass数组中的slab的每个item大小是128字节,那么下一个slab每个item的大小就是128*2,再下一个就是128*2*2(注意,为了简化问题的说明,上面没有考虑地址对齐的因素).<br><br>在预分配内存池时,最多给每个slab保存item的容量是1M内存,这个数值由#define POWER_BLOCK 1048576决定.<br>因此,slab中的几个元素在预分配内存时是这么定的:<br>size有一个起始值,这个值以后的增长由factor决定,增长的过程前面已经阐述过了;<br>perslab保存的是一个slab存放的item数量,因此perslab = POWER_BLOCK / slabclass[i].size;<br>如果预先分配一段内存供使用的话,也就是没有定义DONT_PREALLOC_SLABS宏,那么就调用slabs_preallocate进行预分配内存.<br>其中,end_page_ptr指向这个预分配好的指针,end_page_free表示的是目前空闲可用item的数量,在预分配时,这个值与perslab相同.<br>在这个内存池模型中,每个page实际上是一个数组,数组中每个元素的大小就是这个slab中item的大小.<br><br>另外,slots保存的是释放出来的item指针,sl_total表示总的数量,sl_curr表示的是目前可用的已经释放出来的item数量.<br><br>每一次要分配内存的时候,首先根据需要分配的内存大小在slabclass数组中查找索引最小的一个大于所要求内存的slab,如果slots不为空,那么就从这里返回内存,否则去查找end_page_ptr,如果也没有,那么就只能返回NULL了.<br>每一次释放内存的时候,同样的找到应该返回内存的slab元素,改写前面提到的slot指针和sl_curr数.<br><br>有点仓促,以后再完善~~<br><br><br>
<img src ="http://www.cppblog.com/converse/aggbug/41592.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/converse/" target="_blank">那谁</a> 2008-01-21 23:34 <a href="http://www.cppblog.com/converse/archive/2008/01/21/41592.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>仿STL中的堆算法的一个实现</title><link>http://www.cppblog.com/converse/archive/2007/03/20/20175.html</link><dc:creator>那谁</dc:creator><author>那谁</author><pubDate>Mon, 19 Mar 2007 16:28:00 GMT</pubDate><guid>http://www.cppblog.com/converse/archive/2007/03/20/20175.html</guid><wfw:comment>http://www.cppblog.com/converse/comments/20175.html</wfw:comment><comments>http://www.cppblog.com/converse/archive/2007/03/20/20175.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/converse/comments/commentRss/20175.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/converse/services/trackbacks/20175.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 仿STL中的堆算法的一个实现&nbsp;&nbsp;<a href='http://www.cppblog.com/converse/archive/2007/03/20/20175.html'>阅读全文</a><img src ="http://www.cppblog.com/converse/aggbug/20175.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/converse/" target="_blank">那谁</a> 2007-03-20 00:28 <a href="http://www.cppblog.com/converse/archive/2007/03/20/20175.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>CGL开发手记之一--参考资料</title><link>http://www.cppblog.com/converse/archive/2007/03/18/20083.html</link><dc:creator>那谁</dc:creator><author>那谁</author><pubDate>Sun, 18 Mar 2007 11:40:00 GMT</pubDate><guid>http://www.cppblog.com/converse/archive/2007/03/18/20083.html</guid><wfw:comment>http://www.cppblog.com/converse/comments/20083.html</wfw:comment><comments>http://www.cppblog.com/converse/archive/2007/03/18/20083.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/converse/comments/commentRss/20083.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/converse/services/trackbacks/20083.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 有关CGL写作中经常参考到的资料.&nbsp;&nbsp;<a href='http://www.cppblog.com/converse/archive/2007/03/18/20083.html'>阅读全文</a><img src ="http://www.cppblog.com/converse/aggbug/20083.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/converse/" target="_blank">那谁</a> 2007-03-18 19:40 <a href="http://www.cppblog.com/converse/archive/2007/03/18/20083.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Modern C++ Design(MCD)学习笔记 &amp;&amp; 测试代码(二)</title><link>http://www.cppblog.com/converse/archive/2007/02/04/18340.html</link><dc:creator>那谁</dc:creator><author>那谁</author><pubDate>Sun, 04 Feb 2007 15:18:00 GMT</pubDate><guid>http://www.cppblog.com/converse/archive/2007/02/04/18340.html</guid><wfw:comment>http://www.cppblog.com/converse/comments/18340.html</wfw:comment><comments>http://www.cppblog.com/converse/archive/2007/02/04/18340.html#Feedback</comments><slash:comments>5</slash:comments><wfw:commentRss>http://www.cppblog.com/converse/comments/commentRss/18340.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/converse/services/trackbacks/18340.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 检查是否可以转换以及是否存在继承关系的类<br>&nbsp;&nbsp;<a href='http://www.cppblog.com/converse/archive/2007/02/04/18340.html'>阅读全文</a><img src ="http://www.cppblog.com/converse/aggbug/18340.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/converse/" target="_blank">那谁</a> 2007-02-04 23:18 <a href="http://www.cppblog.com/converse/archive/2007/02/04/18340.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Modern C++ Design(MCD)学习笔记 &amp;&amp; 测试代码(一)</title><link>http://www.cppblog.com/converse/archive/2007/02/04/18325.html</link><dc:creator>那谁</dc:creator><author>那谁</author><pubDate>Sun, 04 Feb 2007 07:53:00 GMT</pubDate><guid>http://www.cppblog.com/converse/archive/2007/02/04/18325.html</guid><wfw:comment>http://www.cppblog.com/converse/comments/18325.html</wfw:comment><comments>http://www.cppblog.com/converse/archive/2007/02/04/18325.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/converse/comments/commentRss/18325.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/converse/services/trackbacks/18325.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 编译期断言模版类的技巧~~&nbsp;&nbsp;<a href='http://www.cppblog.com/converse/archive/2007/02/04/18325.html'>阅读全文</a><img src ="http://www.cppblog.com/converse/aggbug/18325.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/converse/" target="_blank">那谁</a> 2007-02-04 15:53 <a href="http://www.cppblog.com/converse/archive/2007/02/04/18325.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>little endian和big endian的概念解释,判定与用途</title><link>http://www.cppblog.com/converse/archive/2006/09/05/12058.html</link><dc:creator>那谁</dc:creator><author>那谁</author><pubDate>Tue, 05 Sep 2006 13:04:00 GMT</pubDate><guid>http://www.cppblog.com/converse/archive/2006/09/05/12058.html</guid><wfw:comment>http://www.cppblog.com/converse/comments/12058.html</wfw:comment><comments>http://www.cppblog.com/converse/archive/2006/09/05/12058.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.cppblog.com/converse/comments/commentRss/12058.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/converse/services/trackbacks/12058.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: little endian和big endian的概念解释,判定与用途&nbsp;&nbsp;<a href='http://www.cppblog.com/converse/archive/2006/09/05/12058.html'>阅读全文</a><img src ="http://www.cppblog.com/converse/aggbug/12058.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/converse/" target="_blank">那谁</a> 2006-09-05 21:04 <a href="http://www.cppblog.com/converse/archive/2006/09/05/12058.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>测试了一下VC和gcc对关键字export的支持</title><link>http://www.cppblog.com/converse/archive/2006/07/11/9695.html</link><dc:creator>那谁</dc:creator><author>那谁</author><pubDate>Tue, 11 Jul 2006 11:04:00 GMT</pubDate><guid>http://www.cppblog.com/converse/archive/2006/07/11/9695.html</guid><wfw:comment>http://www.cppblog.com/converse/comments/9695.html</wfw:comment><comments>http://www.cppblog.com/converse/archive/2006/07/11/9695.html#Feedback</comments><slash:comments>13</slash:comments><wfw:commentRss>http://www.cppblog.com/converse/comments/commentRss/9695.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/converse/services/trackbacks/9695.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 测试了一下VC和gcc对关键字export的支持&nbsp;&nbsp;<a href='http://www.cppblog.com/converse/archive/2006/07/11/9695.html'>阅读全文</a><img src ="http://www.cppblog.com/converse/aggbug/9695.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/converse/" target="_blank">那谁</a> 2006-07-11 19:04 <a href="http://www.cppblog.com/converse/archive/2006/07/11/9695.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>探索C++的秘密之二:重载,覆盖,和隐藏   </title><link>http://www.cppblog.com/converse/archive/2006/03/24/4564.html</link><dc:creator>那谁</dc:creator><author>那谁</author><pubDate>Fri, 24 Mar 2006 12:39:00 GMT</pubDate><guid>http://www.cppblog.com/converse/archive/2006/03/24/4564.html</guid><wfw:comment>http://www.cppblog.com/converse/comments/4564.html</wfw:comment><comments>http://www.cppblog.com/converse/archive/2006/03/24/4564.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.cppblog.com/converse/comments/commentRss/4564.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/converse/services/trackbacks/4564.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 三个概念重载,覆盖,和隐藏的区别.&nbsp;&nbsp;<a href='http://www.cppblog.com/converse/archive/2006/03/24/4564.html'>阅读全文</a><img src ="http://www.cppblog.com/converse/aggbug/4564.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/converse/" target="_blank">那谁</a> 2006-03-24 20:39 <a href="http://www.cppblog.com/converse/archive/2006/03/24/4564.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>使用typename的一个说明</title><link>http://www.cppblog.com/converse/archive/2006/03/22/4476.html</link><dc:creator>那谁</dc:creator><author>那谁</author><pubDate>Wed, 22 Mar 2006 15:41:00 GMT</pubDate><guid>http://www.cppblog.com/converse/archive/2006/03/22/4476.html</guid><wfw:comment>http://www.cppblog.com/converse/comments/4476.html</wfw:comment><comments>http://www.cppblog.com/converse/archive/2006/03/22/4476.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/converse/comments/commentRss/4476.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/converse/services/trackbacks/4476.html</trackback:ping><description><![CDATA[时常看到这样的代码,比如以下这两段代码:<br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /><span style="COLOR: #000000">list</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">::iterator iter1;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />list</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">T</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">::iterator iter1;</span></div><br />前者没有问题可以顺利的编译过去，但是后者时常会报一个警告，为什么呢?<br />原因如下:<br />首先,list&lt;T&gt;是一个模板类，在模板实例化以前是无法确定起真正的类型的,也就是说编译阶段是无法知道到底是哪个类的,那么可能出现以下一种情况：某个类中恰好有一个静态成员为iterator，此时就会出错了。<br />因此为了明确的指出这是一个类型而不是一个成员，我们需要在前面加上typename，也就是:<br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /><span style="COLOR: #000000">typename list</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">T</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">::iterator iter1;</span></div>typename在这里用于说明后面紧跟着的字符串表示的是一个类型。<img src ="http://www.cppblog.com/converse/aggbug/4476.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/converse/" target="_blank">那谁</a> 2006-03-22 23:41 <a href="http://www.cppblog.com/converse/archive/2006/03/22/4476.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>模板套模板～～</title><link>http://www.cppblog.com/converse/archive/2006/03/22/4445.html</link><dc:creator>那谁</dc:creator><author>那谁</author><pubDate>Tue, 21 Mar 2006 16:06:00 GMT</pubDate><guid>http://www.cppblog.com/converse/archive/2006/03/22/4445.html</guid><wfw:comment>http://www.cppblog.com/converse/comments/4445.html</wfw:comment><comments>http://www.cppblog.com/converse/archive/2006/03/22/4445.html#Feedback</comments><slash:comments>5</slash:comments><wfw:commentRss>http://www.cppblog.com/converse/comments/commentRss/4445.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/converse/services/trackbacks/4445.html</trackback:ping><description><![CDATA[
		<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee">
				<img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />
				<span style="COLOR: #000000">#include </span>
				<span style="COLOR: #000000">&lt;</span>
				<span style="COLOR: #000000">iostream</span>
				<span style="COLOR: #000000">&gt;</span>
				<span style="COLOR: #000000">
						<br />
						<img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />#include </span>
				<span style="COLOR: #000000">&lt;</span>
				<span style="COLOR: #000000">map</span>
				<span style="COLOR: #000000">&gt;</span>
				<span style="COLOR: #000000">
						<br />
						<img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />#include </span>
				<span style="COLOR: #000000">&lt;</span>
				<span style="COLOR: #0000ff">string</span>
				<span style="COLOR: #000000">&gt;</span>
				<span style="COLOR: #000000">
						<br />
						<img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />
						<br />
						<img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />
				</span>
				<span style="COLOR: #0000ff">using</span>
				<span style="COLOR: #000000"> </span>
				<span style="COLOR: #0000ff">namespace</span>
				<span style="COLOR: #000000"> std;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /></span>
				<span style="COLOR: #0000ff">int</span>
				<span style="COLOR: #000000"> main()<br /><img id="Codehighlighter1_87_263_Open_Image" onclick="this.style.display='none'; Codehighlighter1_87_263_Open_Text.style.display='none'; Codehighlighter1_87_263_Closed_Image.style.display='inline'; Codehighlighter1_87_263_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_87_263_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_87_263_Closed_Text.style.display='none'; Codehighlighter1_87_263_Open_Image.style.display='inline'; Codehighlighter1_87_263_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align="top" /></span>
				<span id="Codehighlighter1_87_263_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">
						<img src="http://www.cppblog.com/images/dot.gif" />
				</span>
				<span id="Codehighlighter1_87_263_Open_Text">
						<span style="COLOR: #000000">{<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    map</span>
						<span style="COLOR: #000000">&lt;</span>
						<span style="COLOR: #0000ff">string</span>
						<span style="COLOR: #000000">, </span>
						<span style="COLOR: #0000ff">int</span>
						<span style="COLOR: #000000">&gt;</span>
						<span style="COLOR: #000000"> map1;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    map</span>
						<span style="COLOR: #000000">&lt;</span>
						<span style="COLOR: #0000ff">string</span>
						<span style="COLOR: #000000">, map</span>
						<span style="COLOR: #000000">&lt;</span>
						<span style="COLOR: #0000ff">string</span>
						<span style="COLOR: #000000">, </span>
						<span style="COLOR: #0000ff">int</span>
						<span style="COLOR: #000000">&gt;</span>
						<span style="COLOR: #000000"> </span>
						<span style="COLOR: #000000">&gt;</span>
						<span style="COLOR: #000000"> map2;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    map1[</span>
						<span style="COLOR: #000000">"</span>
						<span style="COLOR: #000000">test</span>
						<span style="COLOR: #000000">"</span>
						<span style="COLOR: #000000">] </span>
						<span style="COLOR: #000000">=</span>
						<span style="COLOR: #000000"> </span>
						<span style="COLOR: #000000">2</span>
						<span style="COLOR: #000000">;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    map2[</span>
						<span style="COLOR: #000000">"</span>
						<span style="COLOR: #000000">test1</span>
						<span style="COLOR: #000000">"</span>
						<span style="COLOR: #000000">] </span>
						<span style="COLOR: #000000">=</span>
						<span style="COLOR: #000000"> map1;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" /><br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    cout </span>
						<span style="COLOR: #000000">&lt;&lt;</span>
						<span style="COLOR: #000000"> map2[</span>
						<span style="COLOR: #000000">"</span>
						<span style="COLOR: #000000">test1</span>
						<span style="COLOR: #000000">"</span>
						<span style="COLOR: #000000">][</span>
						<span style="COLOR: #000000">"</span>
						<span style="COLOR: #000000">test</span>
						<span style="COLOR: #000000">"</span>
						<span style="COLOR: #000000">] </span>
						<span style="COLOR: #000000">&lt;&lt;</span>
						<span style="COLOR: #000000"> endl;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    </span>
						<span style="COLOR: #0000ff">return</span>
						<span style="COLOR: #000000"> </span>
						<span style="COLOR: #000000">0</span>
						<span style="COLOR: #000000">;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span>
				</span>
		</div>以上代码简单的实现了map对"二维"形式的支持,很简单,不是么？可是我第一次面对这个问题的时候模板套模板的整糊涂了,记录一个留个念想～～<img src ="http://www.cppblog.com/converse/aggbug/4445.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/converse/" target="_blank">那谁</a> 2006-03-22 00:06 <a href="http://www.cppblog.com/converse/archive/2006/03/22/4445.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>一个关于临时对象和虚拟析构函数的问题</title><link>http://www.cppblog.com/converse/archive/2006/02/16/3297.html</link><dc:creator>那谁</dc:creator><author>那谁</author><pubDate>Thu, 16 Feb 2006 15:24:00 GMT</pubDate><guid>http://www.cppblog.com/converse/archive/2006/02/16/3297.html</guid><wfw:comment>http://www.cppblog.com/converse/comments/3297.html</wfw:comment><comments>http://www.cppblog.com/converse/archive/2006/02/16/3297.html#Feedback</comments><slash:comments>7</slash:comments><wfw:commentRss>http://www.cppblog.com/converse/comments/commentRss/3297.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/converse/services/trackbacks/3297.html</trackback:ping><description><![CDATA[在CU逛,别人问到这样的一个问题,大致如下:<BR><BR><FONT size=2><FONT color=#0000ff>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top><SPAN style="COLOR: #000000">#include&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">iostream</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top>#include&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #0000ff">string</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #0000ff">using</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">namespace</SPAN><SPAN style="COLOR: #000000">&nbsp;std;<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">base</SPAN><SPAN style="COLOR: #000000"><BR><IMG id=Codehighlighter1_70_210_Open_Image onclick="this.style.display='none'; Codehighlighter1_70_210_Open_Text.style.display='none'; Codehighlighter1_70_210_Closed_Image.style.display='inline'; Codehighlighter1_70_210_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align=top><IMG id=Codehighlighter1_70_210_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_70_210_Closed_Text.style.display='none'; Codehighlighter1_70_210_Open_Image.style.display='inline'; Codehighlighter1_70_210_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align=top></SPAN><SPAN id=Codehighlighter1_70_210_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><IMG src="http://www.cppblog.com/images/dot.gif"></SPAN><SPAN id=Codehighlighter1_70_210_Open_Text><SPAN style="COLOR: #000000">{<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">:<BR><IMG id=Codehighlighter1_124_153_Open_Image onclick="this.style.display='none'; Codehighlighter1_124_153_Open_Text.style.display='none'; Codehighlighter1_124_153_Closed_Image.style.display='inline'; Codehighlighter1_124_153_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><IMG id=Codehighlighter1_124_153_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_124_153_Closed_Text.style.display='none'; Codehighlighter1_124_153_Open_Image.style.display='inline'; Codehighlighter1_124_153_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">virtual</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;print()</SPAN><SPAN id=Codehighlighter1_124_153_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><IMG src="http://www.cppblog.com/images/dot.gif"></SPAN><SPAN id=Codehighlighter1_124_153_Open_Text><SPAN style="COLOR: #000000">{cout</SPAN><SPAN style="COLOR: #000000">&lt;&lt;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">base::print()</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">&lt;&lt;</SPAN><SPAN style="COLOR: #000000">endl;}</SPAN></SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">virtual&nbsp;~base(){}</SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">增加虚析构函数，将导致输出不一致。</SPAN><SPAN style="COLOR: #008000"><BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align=top></SPAN><SPAN style="COLOR: #000000">}</SPAN></SPAN><SPAN style="COLOR: #000000">;<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;derived&nbsp;:</SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">base</SPAN><SPAN style="COLOR: #000000"><BR><IMG id=Codehighlighter1_240_329_Open_Image onclick="this.style.display='none'; Codehighlighter1_240_329_Open_Text.style.display='none'; Codehighlighter1_240_329_Closed_Image.style.display='inline'; Codehighlighter1_240_329_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align=top><IMG id=Codehighlighter1_240_329_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_240_329_Closed_Text.style.display='none'; Codehighlighter1_240_329_Open_Image.style.display='inline'; Codehighlighter1_240_329_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align=top></SPAN><SPAN id=Codehighlighter1_240_329_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><IMG src="http://www.cppblog.com/images/dot.gif"></SPAN><SPAN id=Codehighlighter1_240_329_Open_Text><SPAN style="COLOR: #000000">{<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">:<BR><IMG id=Codehighlighter1_294_327_Open_Image onclick="this.style.display='none'; Codehighlighter1_294_327_Open_Text.style.display='none'; Codehighlighter1_294_327_Closed_Image.style.display='inline'; Codehighlighter1_294_327_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><IMG id=Codehighlighter1_294_327_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_294_327_Closed_Text.style.display='none'; Codehighlighter1_294_327_Open_Image.style.display='inline'; Codehighlighter1_294_327_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">virtual</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;print()</SPAN><SPAN id=Codehighlighter1_294_327_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><IMG src="http://www.cppblog.com/images/dot.gif"></SPAN><SPAN id=Codehighlighter1_294_327_Open_Text><SPAN style="COLOR: #000000">{cout</SPAN><SPAN style="COLOR: #000000">&lt;&lt;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">devrived::print()</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">&lt;&lt;</SPAN><SPAN style="COLOR: #000000">endl;}</SPAN></SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</SPAN></SPAN><SPAN style="COLOR: #000000">;<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;main(</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;argc,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">char</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">argv[])<BR><IMG id=Codehighlighter1_365_498_Open_Image onclick="this.style.display='none'; Codehighlighter1_365_498_Open_Text.style.display='none'; Codehighlighter1_365_498_Closed_Image.style.display='inline'; Codehighlighter1_365_498_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align=top><IMG id=Codehighlighter1_365_498_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_365_498_Closed_Text.style.display='none'; Codehighlighter1_365_498_Open_Image.style.display='inline'; Codehighlighter1_365_498_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align=top></SPAN><SPAN id=Codehighlighter1_365_498_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><IMG src="http://www.cppblog.com/images/dot.gif"></SPAN><SPAN id=Codehighlighter1_365_498_Open_Text><SPAN style="COLOR: #000000">{<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">base</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">&nbsp;p1</SPAN><SPAN style="COLOR: #000000">=&amp;</SPAN><SPAN style="COLOR: #000000">derived();<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;p1</SPAN><SPAN style="COLOR: #000000">-&gt;</SPAN><SPAN style="COLOR: #000000">print();<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top><BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;derived&nbsp;d;<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">base</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">&nbsp;p2</SPAN><SPAN style="COLOR: #000000">=&amp;</SPAN><SPAN style="COLOR: #000000">d;<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;p2</SPAN><SPAN style="COLOR: #000000">-&gt;</SPAN><SPAN style="COLOR: #000000">print();<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top><BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">return</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">;<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</SPAN></SPAN></DIV><BR><BR></FONT>加入虚拟析构函数后，输出为：<BR>base::print()<BR>devrived::print()<BR>不加入虚拟析构函数，输出则为：<BR>devrived::print()<BR>devrived::print()</FONT><BR><BR><BR>我的解释如下:<BR><FONT size=2>实际上,第一个赋值指向的是一个临时对象,加入与没有加入虚拟析构函数的区别在于:加入之后,在derived类中会合成一个析构函数以便调用base的虚拟析构函数,如果没有加入的话那么就不会合成这个析构函数,所有的资源在main函数结束之后才回收.<BR><BR>因此,对于代码: base* p1=&amp;derived();<BR>没有加入虚拟析构函数的时候因为derived()函数生成的临时对象没有被销毁,因此对它的调用是对derived的调用;当加入虚拟析构函数之后,derived()函数生成的临时对象在以上的赋值完成之后就会调用析构函数进行析构,这个时候再次对p1调用print函数时,因为临时对象已经析构,那么这个调用就是对base的调用了.<BR><BR>我做了一个实验的代码,加了一些东西,大家看看~~<BR><BR></FONT>
<DIV class=smalltxt style="FONT-WEIGHT: bold; MARGIN-LEFT: 2em; MARGIN-RIGHT: 2em">
<DIV style="FLOAT: left"></DIV>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top><SPAN style="COLOR: #000000">#include&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">iostream</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top>#include&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #0000ff">string</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #0000ff">using</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">namespace</SPAN><SPAN style="COLOR: #000000">&nbsp;std;<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">base</SPAN><SPAN style="COLOR: #000000"><BR><IMG id=Codehighlighter1_70_229_Open_Image onclick="this.style.display='none'; Codehighlighter1_70_229_Open_Text.style.display='none'; Codehighlighter1_70_229_Closed_Image.style.display='inline'; Codehighlighter1_70_229_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align=top><IMG id=Codehighlighter1_70_229_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_70_229_Closed_Text.style.display='none'; Codehighlighter1_70_229_Open_Image.style.display='inline'; Codehighlighter1_70_229_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align=top></SPAN><SPAN id=Codehighlighter1_70_229_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><IMG src="http://www.cppblog.com/images/dot.gif"></SPAN><SPAN id=Codehighlighter1_70_229_Open_Text><SPAN style="COLOR: #000000">{<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">:<BR><IMG id=Codehighlighter1_124_153_Open_Image onclick="this.style.display='none'; Codehighlighter1_124_153_Open_Text.style.display='none'; Codehighlighter1_124_153_Closed_Image.style.display='inline'; Codehighlighter1_124_153_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><IMG id=Codehighlighter1_124_153_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_124_153_Closed_Text.style.display='none'; Codehighlighter1_124_153_Open_Image.style.display='inline'; Codehighlighter1_124_153_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">virtual</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;print()</SPAN><SPAN id=Codehighlighter1_124_153_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><IMG src="http://www.cppblog.com/images/dot.gif"></SPAN><SPAN id=Codehighlighter1_124_153_Open_Text><SPAN style="COLOR: #000000">{cout</SPAN><SPAN style="COLOR: #000000">&lt;&lt;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">base::print()</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">&lt;&lt;</SPAN><SPAN style="COLOR: #000000">endl;}</SPAN></SPAN><SPAN style="COLOR: #000000"><BR><IMG id=Codehighlighter1_186_208_Open_Image onclick="this.style.display='none'; Codehighlighter1_186_208_Open_Text.style.display='none'; Codehighlighter1_186_208_Closed_Image.style.display='inline'; Codehighlighter1_186_208_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><IMG id=Codehighlighter1_186_208_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_186_208_Closed_Text.style.display='none'; Codehighlighter1_186_208_Open_Image.style.display='inline'; Codehighlighter1_186_208_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">virtual</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">~</SPAN><SPAN style="COLOR: #0000ff">base</SPAN><SPAN style="COLOR: #000000">()</SPAN><SPAN id=Codehighlighter1_186_208_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><IMG src="http://www.cppblog.com/images/dot.gif"></SPAN><SPAN id=Codehighlighter1_186_208_Open_Text><SPAN style="COLOR: #000000">{cout&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">~base()\n</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">;}</SPAN></SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">增加虚析构函数，将导致输出不一致。</SPAN><SPAN style="COLOR: #008000"><BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align=top></SPAN><SPAN style="COLOR: #000000">}</SPAN></SPAN><SPAN style="COLOR: #000000">;<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;derived&nbsp;:</SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">base</SPAN><SPAN style="COLOR: #000000"><BR><IMG id=Codehighlighter1_259_430_Open_Image onclick="this.style.display='none'; Codehighlighter1_259_430_Open_Text.style.display='none'; Codehighlighter1_259_430_Closed_Image.style.display='inline'; Codehighlighter1_259_430_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align=top><IMG id=Codehighlighter1_259_430_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_259_430_Closed_Text.style.display='none'; Codehighlighter1_259_430_Open_Image.style.display='inline'; Codehighlighter1_259_430_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align=top></SPAN><SPAN id=Codehighlighter1_259_430_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><IMG src="http://www.cppblog.com/images/dot.gif"></SPAN><SPAN id=Codehighlighter1_259_430_Open_Text><SPAN style="COLOR: #000000">{<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">:<BR><IMG id=Codehighlighter1_313_346_Open_Image onclick="this.style.display='none'; Codehighlighter1_313_346_Open_Text.style.display='none'; Codehighlighter1_313_346_Closed_Image.style.display='inline'; Codehighlighter1_313_346_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><IMG id=Codehighlighter1_313_346_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_313_346_Closed_Text.style.display='none'; Codehighlighter1_313_346_Open_Image.style.display='inline'; Codehighlighter1_313_346_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">virtual</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;print()</SPAN><SPAN id=Codehighlighter1_313_346_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><IMG src="http://www.cppblog.com/images/dot.gif"></SPAN><SPAN id=Codehighlighter1_313_346_Open_Text><SPAN style="COLOR: #000000">{cout</SPAN><SPAN style="COLOR: #000000">&lt;&lt;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">devrived::print()</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">&lt;&lt;</SPAN><SPAN style="COLOR: #000000">endl;}</SPAN></SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">virtual&nbsp;~derived(){cout&nbsp;&lt;&lt;&nbsp;"~derived()\n";}</SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">增加虚析构函数，将导致输出不一致。</SPAN><SPAN style="COLOR: #008000"><BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align=top></SPAN><SPAN style="COLOR: #000000">}</SPAN></SPAN><SPAN style="COLOR: #000000">;<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top><BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;main(</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;argc,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">char</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">argv[])<BR><IMG id=Codehighlighter1_467_933_Open_Image onclick="this.style.display='none'; Codehighlighter1_467_933_Open_Text.style.display='none'; Codehighlighter1_467_933_Closed_Image.style.display='inline'; Codehighlighter1_467_933_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align=top><IMG id=Codehighlighter1_467_933_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_467_933_Closed_Text.style.display='none'; Codehighlighter1_467_933_Open_Image.style.display='inline'; Codehighlighter1_467_933_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align=top></SPAN><SPAN id=Codehighlighter1_467_933_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><IMG src="http://www.cppblog.com/images/dot.gif"></SPAN><SPAN id=Codehighlighter1_467_933_Open_Text><SPAN style="COLOR: #000000">{<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;derived&nbsp;</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">t&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">&amp;</SPAN><SPAN style="COLOR: #000000">derived();<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">base</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">&nbsp;p1&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;t;<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;p1</SPAN><SPAN style="COLOR: #000000">-&gt;</SPAN><SPAN style="COLOR: #000000">print();<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top><BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;derived&nbsp;d;<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">base</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">&nbsp;p2</SPAN><SPAN style="COLOR: #000000">=&amp;</SPAN><SPAN style="COLOR: #000000">d;<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;p2</SPAN><SPAN style="COLOR: #000000">-&gt;</SPAN><SPAN style="COLOR: #000000">print();<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top><BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">&nbsp;第一部分相当于以下的代码<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">&nbsp;用temp模拟临时对象</SPAN><SPAN style="COLOR: #008000"><BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top></SPAN><SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;derived&nbsp;temp;<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;derived&nbsp;</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">s&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">&amp;</SPAN><SPAN style="COLOR: #000000">temp;<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">base</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">p3&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;s;<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">&nbsp;这次调用是对derived的函数调用</SPAN><SPAN style="COLOR: #008000"><BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top></SPAN><SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;p3</SPAN><SPAN style="COLOR: #000000">-&gt;</SPAN><SPAN style="COLOR: #000000">print();<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">&nbsp;显式地对temp进行析构</SPAN><SPAN style="COLOR: #008000"><BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top></SPAN><SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;temp.</SPAN><SPAN style="COLOR: #0000ff">base</SPAN><SPAN style="COLOR: #000000">::</SPAN><SPAN style="COLOR: #000000">~</SPAN><SPAN style="COLOR: #0000ff">base</SPAN><SPAN style="COLOR: #000000">();<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">&nbsp;析构完后,同样的一个内存,却是用base指针去解释,<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">&nbsp;因此调用的是base的函数</SPAN><SPAN style="COLOR: #008000"><BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top></SPAN><SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;p3</SPAN><SPAN style="COLOR: #000000">-&gt;</SPAN><SPAN style="COLOR: #000000">print();<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top><BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">return</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">;<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</SPAN></SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN></DIV></DIV><img src ="http://www.cppblog.com/converse/aggbug/3297.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/converse/" target="_blank">那谁</a> 2006-02-16 23:24 <a href="http://www.cppblog.com/converse/archive/2006/02/16/3297.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>探索C++的秘密之一详解extern "C"</title><link>http://www.cppblog.com/converse/archive/2006/01/14/2733.html</link><dc:creator>那谁</dc:creator><author>那谁</author><pubDate>Sat, 14 Jan 2006 15:52:00 GMT</pubDate><guid>http://www.cppblog.com/converse/archive/2006/01/14/2733.html</guid><wfw:comment>http://www.cppblog.com/converse/comments/2733.html</wfw:comment><comments>http://www.cppblog.com/converse/archive/2006/01/14/2733.html#Feedback</comments><slash:comments>12</slash:comments><wfw:commentRss>http://www.cppblog.com/converse/comments/commentRss/2733.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/converse/services/trackbacks/2733.html</trackback:ping><description><![CDATA[<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 时常在cpp的代码之中看到这样的代码:<BR></P>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top><SPAN style="COLOR: #000000">#ifdef&nbsp;__cplusplus<BR><IMG id=Codehighlighter1_30_70_Open_Image onclick="this.style.display='none'; Codehighlighter1_30_70_Open_Text.style.display='none'; Codehighlighter1_30_70_Closed_Image.style.display='inline'; Codehighlighter1_30_70_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align=top><IMG id=Codehighlighter1_30_70_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_30_70_Closed_Text.style.display='none'; Codehighlighter1_30_70_Open_Image.style.display='inline'; Codehighlighter1_30_70_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align=top></SPAN><SPAN style="COLOR: #0000ff">extern</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">C</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN id=Codehighlighter1_30_70_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><IMG src="http://www.cppblog.com/images/dot.gif"></SPAN><SPAN id=Codehighlighter1_30_70_Open_Text><SPAN style="COLOR: #000000">{<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top></SPAN><SPAN style="COLOR: #0000ff">#endif</SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top><BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top></SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000"><IMG src="http://www.cppblog.com/images/dot.gif">一段代码</SPAN><SPAN style="COLOR: #008000"><BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top></SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top>#ifdef&nbsp;__cplusplus<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</SPAN></SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #0000ff">#endif</SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top><BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top></SPAN></DIV>
<P><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 这样的代码到底是什么意思呢?首先,__cplusplus是cpp中的自定义宏,那么定义了这个宏的话表示这是一段cpp的代码,也就是说,上面的代码的含义是:如果这是一段cpp的代码,那么加入extern "C"{和}处理其中的代码.</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 要明白为何使用extern "C",还得从cpp中对函数的重载处理开始说起.在c++中,为了支持重载机制,在编译生成的汇编码中,要对函数的名字进行一些处理,加入比如函数的返回类型等等.而在C中,只是简单的函数名字而已,不会加入其他的信息.也就是说:C++和C对产生的函数名字的处理是不一样的.</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 比如下面的一段简单的函数,我们看看加入和不加入extern "C"产生的汇编代码都有哪些变化:</P>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;f(</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">)<BR><IMG id=Codehighlighter1_12_28_Open_Image onclick="this.style.display='none'; Codehighlighter1_12_28_Open_Text.style.display='none'; Codehighlighter1_12_28_Closed_Image.style.display='inline'; Codehighlighter1_12_28_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align=top><IMG id=Codehighlighter1_12_28_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_12_28_Closed_Text.style.display='none'; Codehighlighter1_12_28_Open_Image.style.display='inline'; Codehighlighter1_12_28_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align=top></SPAN><SPAN id=Codehighlighter1_12_28_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><IMG src="http://www.cppblog.com/images/dot.gif"></SPAN><SPAN id=Codehighlighter1_12_28_Open_Text><SPAN style="COLOR: #000000">{<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">return</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">1</SPAN><SPAN style="COLOR: #000000">;<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</SPAN></SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top></SPAN></DIV>
<P><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 在加入extern "C"的时候产生的汇编代码是:<BR></P>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top><SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;.file&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">test.cxx</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;.text<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;.align&nbsp;</SPAN><SPAN style="COLOR: #000000">2</SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top>.globl&nbsp;_f<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;.def&nbsp;&nbsp;&nbsp;&nbsp;_f;&nbsp;&nbsp;&nbsp;&nbsp;.scl&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #000000">2</SPAN><SPAN style="COLOR: #000000">;&nbsp;&nbsp;&nbsp;&nbsp;.type&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #000000">32</SPAN><SPAN style="COLOR: #000000">;&nbsp;&nbsp;&nbsp;&nbsp;.endef<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top>_f:<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;pushl&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #000000">%</SPAN><SPAN style="COLOR: #000000">ebp<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;movl&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #000000">%</SPAN><SPAN style="COLOR: #000000">esp,&nbsp;</SPAN><SPAN style="COLOR: #000000">%</SPAN><SPAN style="COLOR: #000000">ebp<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;movl&nbsp;&nbsp;&nbsp;&nbsp;$</SPAN><SPAN style="COLOR: #000000">1</SPAN><SPAN style="COLOR: #000000">,&nbsp;</SPAN><SPAN style="COLOR: #000000">%</SPAN><SPAN style="COLOR: #000000">eax<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;popl&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #000000">%</SPAN><SPAN style="COLOR: #000000">ebp<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;ret</SPAN></DIV>
<P><BR>但是不加入了extern "C"之后<BR></P>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top><SPAN style="COLOR: #000000">&nbsp;.file&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">test.cxx</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top>&nbsp;.text<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top>&nbsp;.align&nbsp;</SPAN><SPAN style="COLOR: #000000">2</SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top>.globl&nbsp;__Z1fv<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top>&nbsp;.def&nbsp;__Z1fv;&nbsp;.scl&nbsp;</SPAN><SPAN style="COLOR: #000000">2</SPAN><SPAN style="COLOR: #000000">;&nbsp;.type&nbsp;</SPAN><SPAN style="COLOR: #000000">32</SPAN><SPAN style="COLOR: #000000">;&nbsp;.endef<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top>__Z1fv:<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top>&nbsp;pushl&nbsp;</SPAN><SPAN style="COLOR: #000000">%</SPAN><SPAN style="COLOR: #000000">ebp<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top>&nbsp;movl&nbsp;</SPAN><SPAN style="COLOR: #000000">%</SPAN><SPAN style="COLOR: #000000">esp,&nbsp;</SPAN><SPAN style="COLOR: #000000">%</SPAN><SPAN style="COLOR: #000000">ebp<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top>&nbsp;movl&nbsp;$</SPAN><SPAN style="COLOR: #000000">1</SPAN><SPAN style="COLOR: #000000">,&nbsp;</SPAN><SPAN style="COLOR: #000000">%</SPAN><SPAN style="COLOR: #000000">eax<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top>&nbsp;popl&nbsp;</SPAN><SPAN style="COLOR: #000000">%</SPAN><SPAN style="COLOR: #000000">ebp<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top>&nbsp;ret</SPAN></DIV>
<P><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 两段汇编代码同样都是使用gcc -S命令产生的,所有的地方都是一样的,<BR>唯独是产生的函数名,一个是_f,一个是__Z1fv.</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; OK,明白了加入与不加入extern "C"之后对函数名称产生的影响,我们继续我们的讨论:为什么需要使用extern "C"呢?<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; C++之父在设计C++之时,考虑到当时已经存在了大量的C代码,为了支持原来的C代码和已经写好C库,需要在C++中尽可能的支持C,而extern "C"就是其中的一个策略.</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 试想这样的情况:一个库文件已经用C写好了而且运行得很良好,这个时候我们需要使用这个库文件,但是我们需要使用C++来写这个新的代码.如果这个代码使用的是C++的方式链接这个C库文件的话,那么就会出现链接错误.我们来看一段代码:首先,我们使用C的处理方式来写一个函数,也就是说假设这个函数当时是用C写成的:</P>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">f1.c</SPAN><SPAN style="COLOR: #008000"><BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #0000ff">extern</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">C</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000"><BR><IMG id=Codehighlighter1_18_46_Open_Image onclick="this.style.display='none'; Codehighlighter1_18_46_Open_Text.style.display='none'; Codehighlighter1_18_46_Closed_Image.style.display='inline'; Codehighlighter1_18_46_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align=top><IMG id=Codehighlighter1_18_46_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_18_46_Closed_Text.style.display='none'; Codehighlighter1_18_46_Open_Image.style.display='inline'; Codehighlighter1_18_46_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align=top></SPAN><SPAN id=Codehighlighter1_18_46_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><IMG src="http://www.cppblog.com/images/dot.gif"></SPAN><SPAN id=Codehighlighter1_18_46_Open_Text><SPAN style="COLOR: #000000">{<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top></SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;f1()<BR><IMG id=Codehighlighter1_30_44_Open_Image onclick="this.style.display='none'; Codehighlighter1_30_44_Open_Text.style.display='none'; Codehighlighter1_30_44_Closed_Image.style.display='inline'; Codehighlighter1_30_44_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><IMG id=Codehighlighter1_30_44_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_30_44_Closed_Text.style.display='none'; Codehighlighter1_30_44_Open_Image.style.display='inline'; Codehighlighter1_30_44_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedSubBlock.gif" align=top></SPAN><SPAN id=Codehighlighter1_30_44_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><IMG src="http://www.cppblog.com/images/dot.gif"></SPAN><SPAN id=Codehighlighter1_30_44_Open_Text><SPAN style="COLOR: #000000">{<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">return</SPAN><SPAN style="COLOR: #000000">;<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>}</SPAN></SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</SPAN></SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top></SPAN></DIV>
<P>编译命令是:gcc -c f1.c -o f1.o&nbsp;&nbsp; 产生了一个叫f1.o的库文件.<BR>再写一段代码调用这个f1函数:</P>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">&nbsp;test.cxx<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">这个extern表示f1函数在别的地方定义,这样可以通过<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">编译,但是链接的时候还是需要<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">链接上原来的库文件.</SPAN><SPAN style="COLOR: #008000"><BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #0000ff">extern</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;f1();<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top><BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;main()<BR><IMG id=Codehighlighter1_103_130_Open_Image onclick="this.style.display='none'; Codehighlighter1_103_130_Open_Text.style.display='none'; Codehighlighter1_103_130_Closed_Image.style.display='inline'; Codehighlighter1_103_130_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align=top><IMG id=Codehighlighter1_103_130_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_103_130_Closed_Text.style.display='none'; Codehighlighter1_103_130_Open_Image.style.display='inline'; Codehighlighter1_103_130_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align=top></SPAN><SPAN id=Codehighlighter1_103_130_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><IMG src="http://www.cppblog.com/images/dot.gif"></SPAN><SPAN id=Codehighlighter1_103_130_Open_Text><SPAN style="COLOR: #000000">{<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;f1();<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top><BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">return</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">;<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</SPAN></SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top><BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top></SPAN></DIV>
<P>通过gcc -c&nbsp; test.cxx -o test.o 产生一个叫test.o的文件.<BR>然后,我们使用gcc test.o f1.o来链接两个文件,可是出错了,错误的提示是:<BR>test.o(.text + 0x1f):test.cxx: undefine reference to 'f1()'<BR>也就是说,在编译test.cxx的时候编译器是使用C++的方式来处理f1()函数的,但是实际上链接的库文件却是用C的方式来处理函数的,所以就会出现链接过不去的错误:因为链接器找不到函数.<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;因此,为了在C++代码中调用用C写成的库文件,就需要用extern "C"来告诉编译器:这是一个用C写成的库文件,请用C的方式来链接它们.<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 比如,现在我们有了一个C库文件,它的头文件是f.h,产生的lib文件是f.lib,那么我们如果要在C++中使用这个库文件,我们需要这样写:</P>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top><SPAN style="COLOR: #0000ff">extern</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">C</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000"><BR><IMG id=Codehighlighter1_11_28_Open_Image onclick="this.style.display='none'; Codehighlighter1_11_28_Open_Text.style.display='none'; Codehighlighter1_11_28_Closed_Image.style.display='inline'; Codehighlighter1_11_28_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align=top><IMG id=Codehighlighter1_11_28_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_11_28_Closed_Text.style.display='none'; Codehighlighter1_11_28_Open_Image.style.display='inline'; Codehighlighter1_11_28_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align=top></SPAN><SPAN id=Codehighlighter1_11_28_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><IMG src="http://www.cppblog.com/images/dot.gif"></SPAN><SPAN id=Codehighlighter1_11_28_Open_Text><SPAN style="COLOR: #000000">{<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top>#include&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">f.h</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</SPAN></SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top></SPAN></DIV>
<P>回到上面的问题,如果要改正链接错误,我们需要这样子改写test.cxx:<BR></P>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top><SPAN style="COLOR: #0000ff">extern</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">C</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000"><BR><IMG id=Codehighlighter1_11_31_Open_Image onclick="this.style.display='none'; Codehighlighter1_11_31_Open_Text.style.display='none'; Codehighlighter1_11_31_Closed_Image.style.display='inline'; Codehighlighter1_11_31_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align=top><IMG id=Codehighlighter1_11_31_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_11_31_Closed_Text.style.display='none'; Codehighlighter1_11_31_Open_Image.style.display='inline'; Codehighlighter1_11_31_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align=top></SPAN><SPAN id=Codehighlighter1_11_31_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><IMG src="http://www.cppblog.com/images/dot.gif"></SPAN><SPAN id=Codehighlighter1_11_31_Open_Text><SPAN style="COLOR: #000000">{<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top></SPAN><SPAN style="COLOR: #0000ff">extern</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;f1();<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</SPAN></SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top><BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;main()<BR><IMG id=Codehighlighter1_45_72_Open_Image onclick="this.style.display='none'; Codehighlighter1_45_72_Open_Text.style.display='none'; Codehighlighter1_45_72_Closed_Image.style.display='inline'; Codehighlighter1_45_72_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align=top><IMG id=Codehighlighter1_45_72_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_45_72_Closed_Text.style.display='none'; Codehighlighter1_45_72_Open_Image.style.display='inline'; Codehighlighter1_45_72_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align=top></SPAN><SPAN id=Codehighlighter1_45_72_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><IMG src="http://www.cppblog.com/images/dot.gif"></SPAN><SPAN id=Codehighlighter1_45_72_Open_Text><SPAN style="COLOR: #000000">{<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;f1();<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top><BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">return</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">;<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</SPAN></SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top><BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top></SPAN></DIV>
<P>重新编译并且链接就可以过去了.</P>
<P>总结:C和C++对函数的处理方式是不同的.extern "C"是使C++能够调用C写作的库文件的一个手段,如果要对编译器提示使用C的方式来处理函数的话,那么就要使用extern "C"来说明.</P>
<P>&nbsp;</P>
<P>&nbsp;</P>
<P>&nbsp;</P><img src ="http://www.cppblog.com/converse/aggbug/2733.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/converse/" target="_blank">那谁</a> 2006-01-14 23:52 <a href="http://www.cppblog.com/converse/archive/2006/01/14/2733.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>