﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-清风竹林-随笔分类-语法试炼</title><link>http://www.cppblog.com/xmli/category/8122.html</link><description>ぷ雪飘绛梅映残红 &lt;br&gt;
&amp;nbsp;&amp;nbsp; ぷ花舞霜飞映苍松&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;----- Do more,suffer less</description><language>zh-cn</language><lastBuildDate>Tue, 07 Dec 2010 14:14:45 GMT</lastBuildDate><pubDate>Tue, 07 Dec 2010 14:14:45 GMT</pubDate><ttl>60</ttl><item><title>C++多态技术（转）</title><link>http://www.cppblog.com/xmli/archive/2010/12/07/135666.html</link><dc:creator>李现民</dc:creator><author>李现民</author><pubDate>Tue, 07 Dec 2010 02:52:00 GMT</pubDate><guid>http://www.cppblog.com/xmli/archive/2010/12/07/135666.html</guid><wfw:comment>http://www.cppblog.com/xmli/comments/135666.html</wfw:comment><comments>http://www.cppblog.com/xmli/archive/2010/12/07/135666.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/xmli/comments/commentRss/135666.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/xmli/services/trackbacks/135666.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 作者：荣耀提交者：eastvc 发布日期：2003-12-14 19:38:12原文出处：http://www.royaloo.com/articles/articles_2003/PolymorphismInCpp_content.htm摘要本文描述了C++中的各种多态性。重点阐述了面向对象的动态多态和基于模板的静态多态，并初步探讨了两种技术的结合使用。&nbsp;关键词多态&nbsp; 继承&...&nbsp;&nbsp;<a href='http://www.cppblog.com/xmli/archive/2010/12/07/135666.html'>阅读全文</a><img src ="http://www.cppblog.com/xmli/aggbug/135666.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/xmli/" target="_blank">李现民</a> 2010-12-07 10:52 <a href="http://www.cppblog.com/xmli/archive/2010/12/07/135666.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>关于常量折叠(转)</title><link>http://www.cppblog.com/xmli/archive/2010/11/23/134425.html</link><dc:creator>李现民</dc:creator><author>李现民</author><pubDate>Tue, 23 Nov 2010 13:24:00 GMT</pubDate><guid>http://www.cppblog.com/xmli/archive/2010/11/23/134425.html</guid><wfw:comment>http://www.cppblog.com/xmli/comments/134425.html</wfw:comment><comments>http://www.cppblog.com/xmli/archive/2010/11/23/134425.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/xmli/comments/commentRss/134425.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/xmli/services/trackbacks/134425.html</trackback:ping><description><![CDATA[
<span style="color: rgb(48, 48, 48); font-family: Verdana, Helvetica, Arial; line-height: 21px; font-size: 11.6667px; "><p>首先来看一个例子：</p><p>int main(int argc, char* argv[])<br>{<br>const int i=0;<br>int *j = (int *) &amp;i;<br>*j=1;<br>cout&lt;&lt;&amp;i&lt;&lt;endlcout&lt;&lt;j&lt;&lt;endl;<br>cout&lt;&lt;i&lt;&lt;endl;<br>cout&lt;&lt;*j&lt;&lt;endl;<br>return 0;<br>}</p><p>结果是</p><p>0012ff7c<br>0012ff7c</p><p>0</p><p>1</p><p>因为i和j都指向相同的内存地址，所以输出的前两个结果是相同的，但为啥相同的内存里的结果不相同么？－－这就是常量折叠.</p><p>这个"常量折叠"是 就是在编译器进行语法分析的时候，将常量表达式计算求值，并用求得的值来替换表达式，放入常量表。可以算作一种编译优化。<br>我只是改了这个地址内容,但是i还是0,</p><p>因为编译器在优化的过程中，会把碰见的const全部以内容替换掉（跟宏似的: #define pi 3.1415,用到pi时就用3.1415代替），这个出现在预编译阶段；但是在运行阶段，它的内存里存的东西确实改变了!!!</p><p>6.网上的一些问题（4）</p><br><p>关于常量</p><p>这些天被常量的一些概念折磨着,现在终于有些明白了，</p><p>问题始于const int i = 10;//i存在哪，10存在哪</p><p>说明一：符号表</p><p>这个语句是对i的声明，因为编译器一开始就知道i的值，所以以后出现i时就会用10代替，这好像叫做符号表的概念，i就对应10了。</p><p>网上一篇帖子上有这样的代码：</p><p>const int a = 3;</p><p>int *p = const_cast&lt;int *&gt;(&amp;a);</p><p>*p = 4;</p><p>cout &lt;&lt; a;//仍然输出3</p><p>这个结果可以用上面的说明来解释</p><p>说明二：常量折叠（const folding）与复写传播 (copy propagation)</p><p>网上人们普遍反映thinking in c++将const folding译为常量折叠是种误导，我觉得译的还行，本来folding就有折叠的意思，就是把原来的东西变小，而象const int i = 2*2;编译器确实将2*2算成4了，以后碰到i就用4替换，这个计算2*2的过程据说叫常量折叠--const folding，而用4替换i的过程叫做复写传播--copy propagation.他们都是编译器的优化技术</p><br><p>说明三：为常量分配空间</p><p>补充一下，这里说的都是const 定义的常量，而非文字常量，</p><p>（c++ primer翻译成文字常量--literal constant</p><p>the c++ programming language（tcpl）翻译成文字量，还分了不同类型）</p><p>至于文字常量存在哪，c++ primer 3ed上说它们是不可寻址的--nonaddressable，尽管它们也存在机器内存某个地方，但无法访问它们的地址</p><p>对于int double等类型还好理解，但是对于字符串常量（tcpl里说将字符串文字量作为常量，利于存储与访问时的优化）下面的代码似乎表示字符串常量存储在静态存储区里（字符串文字量是静态分配的--tcpl），那么字符串常量的地址不是可以访问了吗，在静态存储区里</p><p><a href="http://bbs.bc-cn.net/dispbbs.asp?boardid=56&amp;replyi" style="color: rgb(54, 105, 0); text-decoration: none; ">http://bbs.bc-cn.net/dispbbs.asp?boardid=56&amp;replyi</a>...</p><p>字符串文字量的类型是常量字符数组--适当个数的const字符的数组</p><p>//有关字符常量的存储区的问题</p><p>//另外，char a[]和char *a的区别</p><p>//"hello world 1"存在哪<br>#include &lt;iostream&gt;<br>using namespace std;<br>int main()<br>{</p><p><br>char* p = "hello world1"；<br>char a[] = "hello world2"；<br>//会为a在栈上分配13个字节的空间<br>// p[2] = a;<br>a[2] = a;<br>char* p1 = "hello world1"<br>printf("%xn",&amp;p[2]);//p应该指向常量区<br>printf("%x",&amp;a[2]);//栈上数组第三个元素的地址<br>return 0;<br>//结果42f036 //这是常量区<br>//12ff6e果然不一样，这是栈区<br>}</p><br><p>6.总结</p><p>那么"常量折叠"到底是啥意思呢？</p><p>我理解，简单的说就是，当编译器处理const的时候，编译器会将其变成一个立即数。</p><p>《thinking in c++》里面说这一点在数组定义里尤其重要(为啥呢？没有查到相关的资料)。</p><p class="zoundry_bw_tags"><span class="ztags"><span class="ztagspace">Technorati</span>&nbsp;:&nbsp;<a href="http://technorati.com/tag/Zoundary" class="ztag" rel="tag" style="color: rgb(54, 105, 0); text-decoration: none; ">Zoundary</a>,&nbsp;<a href="http://technorati.com/tag/test" class="ztag" rel="tag" style="color: rgb(54, 105, 0); text-decoration: none; ">test</a>,&nbsp;<a href="http://technorati.com/tag/%E5%B8%B8%E9%87%8F%E6%8A%98%E5%8F%A0" class="ztag" rel="tag" style="color: rgb(54, 105, 0); text-decoration: none; ">常量折叠</a></span></p></span><img src ="http://www.cppblog.com/xmli/aggbug/134425.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/xmli/" target="_blank">李现民</a> 2010-11-23 21:24 <a href="http://www.cppblog.com/xmli/archive/2010/11/23/134425.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>const灵异现象</title><link>http://www.cppblog.com/xmli/archive/2010/11/22/134275.html</link><dc:creator>李现民</dc:creator><author>李现民</author><pubDate>Mon, 22 Nov 2010 07:16:00 GMT</pubDate><guid>http://www.cppblog.com/xmli/archive/2010/11/22/134275.html</guid><wfw:comment>http://www.cppblog.com/xmli/comments/134275.html</wfw:comment><comments>http://www.cppblog.com/xmli/archive/2010/11/22/134275.html#Feedback</comments><slash:comments>14</slash:comments><wfw:commentRss>http://www.cppblog.com/xmli/comments/commentRss/134275.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/xmli/services/trackbacks/134275.html</trackback:ping><description><![CDATA[

<p align="CENTER" style="margin-bottom: 0cm"><font color="#000000"><font face="Times New Roman, serif"><font size="4" style="font-size: 16pt"><strong>const</strong></font></font><font size="4" style="font-size: 16pt"><strong>灵异现象</strong></font></font></p>
<p align="CENTER" style="margin-bottom: 0cm">版本：<font face="Times New Roman, serif">0.1</font></p>
<p align="CENTER" style="margin-bottom: 0cm">最后修改：<font face="Times New Roman, serif">2010-11-22</font></p>
<p align="CENTER" style="margin-bottom: 0cm">撰写：李现民</p>
<p lang="zh-CN" align="CENTER" style="margin-bottom: 0cm"><br>
</p>
<h1 class="cjk">概述</h1>
<p style="margin-bottom: 0cm"><font face="Times New Roman, serif">	const</font><span lang="zh-CN">在</span><font face="Times New Roman, serif">c++</font><span lang="zh-CN">中意味着&#8220;不可改变&#8221;，但在有些情况下我们可以&#8220;合法&#8221;地绕过编译器去修改一些</span><font face="Times New Roman, serif">const</font><span lang="zh-CN">数据，比如</span><font face="Times New Roman, serif">const_cast</font><span lang="zh-CN">就可以剥离一个对象的</span><font face="Times New Roman, serif">const</font><span lang="zh-CN">属性。然而，我们这样做在多大程度上是&#8220;合理&#8221;的，却因不同的问题而论，也许一不小心，你就可能掉入陷阱之中。</span></p>
<p lang="zh-CN" style="margin-bottom: 0cm"><font face="Times New Roman, serif">	</font>以下问题，我只分析，不说话，请各位看官自己判断。</p>
<p lang="zh-CN" style="margin-bottom: 0cm"><br>
</p>
<h2 class="cjk">当<span lang="zh-CN">目标</span>是一个常数</h2>
<p lang="zh-CN" align="LEFT" style="margin-bottom: 0cm"><font face="Times New Roman, serif">	</font>这件事源于在网上看到的一篇文章，其来源已经不可考，但大意是：就如下<font face="Times New Roman, serif">C++</font>程序，其输出是什么：</p>
<p align="LEFT" style="margin-bottom: 0cm; background: #e6e6e6"><font face="Times New Roman, serif"><font color="#0000ff"><font size="2" style="font-size: 9pt"><span lang="zxx">void</span></font></font><font color="#000000"><font size="2" style="font-size: 9pt"><span lang="zxx">
</span></font></font><font color="#010001"><font size="2" style="font-size: 9pt"><span lang="zxx">foo</span></font></font><font color="#000000"><font size="2" style="font-size: 9pt"><span lang="zxx">()<br></span></font></font></font><span style="font-family: 'Times New Roman', serif; font-size: 14.4px; ">{<br></span><span style="font-family: 'Times New Roman', serif; "><font color="#0000ff"><font size="2" style="font-size: 9pt"><span lang="zxx">const</span></font></font><font color="#000000"><font size="2" style="font-size: 9pt"><span lang="zxx">
</span></font></font><font color="#0000ff"><font size="2" style="font-size: 9pt"><span lang="zxx">int</span></font></font><font color="#000000"><font size="2" style="font-size: 9pt"><span lang="zxx">
</span></font></font><font color="#010001"><font size="2" style="font-size: 9pt"><span lang="zxx">a</span></font></font><font color="#000000"><font size="2" style="font-size: 9pt"><span lang="zxx">	=
1;<br></span></font></font></span><span style="font-family: 'Times New Roman', serif; "><font color="#0000ff"><font size="2" style="font-size: 9pt"><span lang="zxx">int</span></font></font><font color="#000000"><font size="2" style="font-size: 9pt"><span lang="zxx">*
</span></font></font><font color="#010001"><font size="2" style="font-size: 9pt"><span lang="zxx">p</span></font></font><font color="#000000"><font size="2" style="font-size: 9pt"><span lang="zxx">		=
</span></font></font><font color="#0000ff"><font size="2" style="font-size: 9pt"><span lang="zxx">const_cast</span></font></font><font color="#000000"><font size="2" style="font-size: 9pt"><span lang="zxx">&lt;</span></font></font><font color="#0000ff"><font size="2" style="font-size: 9pt"><span lang="zxx">int</span></font></font><font color="#000000"><font size="2" style="font-size: 9pt"><span lang="zxx">*&gt;(&amp;</span></font></font><font color="#010001"><font size="2" style="font-size: 9pt"><span lang="zxx">a</span></font></font><font color="#000000"><font size="2" style="font-size: 9pt"><span lang="zxx">);<br></span></font></font></span><span style="font-family: 'Times New Roman', serif; "><font color="#000000"><font size="2" style="font-size: 9pt"><span lang="zxx">*</span></font></font><font color="#010001"><font size="2" style="font-size: 9pt"><span lang="zxx">p</span></font></font><font color="#000000"><font size="2" style="font-size: 9pt"><span lang="zxx">		=
2;<br></span></font></font></span><span style="font-family: 'Times New Roman', serif; "><font color="#010001"><font size="2" style="font-size: 9pt"><span lang="zxx">printf</span></font></font><font color="#000000"><font size="2" style="font-size: 9pt"><span lang="zxx">(</span></font></font><font color="#a31515"><font size="2" style="font-size: 9pt"><span lang="zxx">"
a=	%d\n *p=	%d\n &amp;a=	%x\n p=	%x \n\n"</span></font></font><font color="#000000"><font size="2" style="font-size: 9pt"><span lang="zxx">,
</span></font></font><font color="#010001"><font size="2" style="font-size: 9pt"><span lang="zxx">a</span></font></font><font color="#000000"><font size="2" style="font-size: 9pt"><span lang="zxx">,
*</span></font></font><font color="#010001"><font size="2" style="font-size: 9pt"><span lang="zxx">p</span></font></font><font color="#000000"><font size="2" style="font-size: 9pt"><span lang="zxx">,
&amp;</span></font></font><font color="#010001"><font size="2" style="font-size: 9pt"><span lang="zxx">a</span></font></font><font color="#000000"><font size="2" style="font-size: 9pt"><span lang="zxx">,
</span></font></font><font color="#010001"><font size="2" style="font-size: 9pt"><span lang="zxx">p</span></font></font><font color="#000000"><font size="2" style="font-size: 9pt"><span lang="zxx">);<br></span></font></font></span><span style="font-family: 'Times New Roman', serif; font-size: 14.4px; ">}</span></p>
<p lang="zh-CN" align="LEFT" style="margin-bottom: 0cm"><br>
</p>
<p lang="zh-CN" align="LEFT" style="margin-bottom: 0cm"><font face="Times New Roman, serif">	</font>我在<font face="Times New Roman, serif">VC2008</font>下的实测结果为：</p>
<p lang="zh-CN" align="LEFT" style="margin-bottom: 0cm; background: #e6e6e6">
 <font face="Times New Roman, serif">a	=    1<br></font><span style="font-family: 'Times New Roman', serif; ">*p	=    2<br></span><span style="font-family: 'Times New Roman', serif; ">&amp;a	=    12ff6c<br></span><span style="font-family: 'Times New Roman', serif; ">p	=    12ff6c</span></p>
<p lang="zh-CN" align="LEFT" style="margin-bottom: 0cm"><br>
</p>
<p align="LEFT" style="margin-bottom: 0cm"><font face="Times New Roman, serif">	</font><span lang="zh-CN">好了，问题出现：</span><font color="#800000"><span lang="zh-CN">明明</span><font face="Times New Roman, serif">p</font></font><font color="#800000"><span lang="zh-CN">所指向的就是变量</span><font face="Times New Roman, serif">a</font></font><font color="#800000"><span lang="zh-CN">，但为何打印其值时</span><font face="Times New Roman, serif">a!=*p</font></font><span lang="zh-CN">？</span></p>
<p lang="zh-CN" align="LEFT" style="margin-bottom: 0cm"><font face="Times New Roman, serif">	</font>这并非是我用错了<font face="Times New Roman, serif">const_cast</font>，也不是编译器进行了优化的问题。事实上，在各版本的<font face="Times New Roman, serif">VC</font>与<font face="Times New Roman, serif">g++</font>下的运行结果均是如此。</p>
<p lang="zh-CN" align="LEFT" style="margin-bottom: 0cm"><font face="Times New Roman, serif">	</font>以下是<font face="Times New Roman, serif">VC2008</font>下<font face="Times New Roman, serif">debug</font>版本的汇编代码：</p>
<p lang="zh-CN" align="LEFT" style="margin-bottom: 0cm; background: #e6e6e6">
<font face="Times New Roman, serif"><font size="2" style="font-size: 9pt"><span lang="zxx">	const
int a	= 1;<br></span></font></font><span style="color: rgb(128, 128, 128); font-family: 'Times New Roman', serif; font-size: 14.4px; ">0041146E
 mov         dword ptr [a],1<br></span><span style="font-family: 'Times New Roman', serif; font-size: 14.4px; ">int*
p		= const_cast&lt;int*&gt;(&amp;a);<br></span><span style="color: rgb(128, 128, 128); font-family: 'Times New Roman', serif; font-size: 14.4px; ">00411475
 lea           eax,[a]<br></span><span style="color: rgb(128, 128, 128); font-family: 'Times New Roman', serif; font-size: 14.4px; ">00411478
 mov         dword ptr [p],eax<br></span><span style="font-family: 'Times New Roman', serif; font-size: 14.4px; ">*p			=
2;<br></span><span style="color: rgb(128, 128, 128); font-family: 'Times New Roman', serif; font-size: 14.4px; ">0041147B
 mov         eax,dword ptr [p]<br></span><span style="color: rgb(128, 128, 128); font-family: 'Times New Roman', serif; font-size: 14.4px; ">0041147E
 mov         dword ptr [eax],2<br></span><span style="font-family: 'Times New Roman', serif; font-size: 14.4px; ">printf("
a=	%d\n *p=	%d\n &amp;a=	%x\n p=	%x \n\n", a, *p, &amp;a, p);<br></span><span style="color: rgb(128, 128, 128); font-family: 'Times New Roman', serif; font-size: 14.4px; ">00411484
 mov         esi,esp<br></span><span style="color: rgb(128, 128, 128); font-family: 'Times New Roman', serif; font-size: 14.4px; ">00411486
 mov         eax,dword ptr [p]<br></span><span style="color: rgb(128, 128, 128); font-family: 'Times New Roman', serif; font-size: 14.4px; ">00411489
 push        eax<br></span><span style="color: rgb(128, 128, 128); font-family: 'Times New Roman', serif; font-size: 14.4px; ">0041148A
 lea         ecx,[a]<br></span><span style="color: rgb(128, 128, 128); font-family: 'Times New Roman', serif; font-size: 14.4px; ">0041148D
 push        ecx<br></span><span style="color: rgb(128, 128, 128); font-family: 'Times New Roman', serif; font-size: 14.4px; ">0041148E
 mov         edx,dword ptr [p]<br></span><span style="color: rgb(128, 128, 128); font-family: 'Times New Roman', serif; font-size: 14.4px; ">00411491
 mov         eax,dword ptr [edx]<br></span><span style="color: rgb(128, 128, 128); font-family: 'Times New Roman', serif; font-size: 14.4px; ">00411493
 push        eax<br></span><span style="color: rgb(128, 0, 0); font-family: 'Times New Roman', serif; font-size: 14.4px; ">00411494
 push        1<br></span><span style="color: rgb(128, 128, 128); font-family: 'Times New Roman', serif; font-size: 14.4px; ">00411496
 push        offset string " a=\t%d\n *p=\t%d\n &amp;a=\t%x\n
p=\t%x \n\n"... (415808h)<br></span><span style="color: rgb(128, 128, 128); font-family: 'Times New Roman', serif; font-size: 14.4px; ">0041149B
 call        dword ptr [__imp__printf (419318h)]</span></p>
<p lang="zh-CN" align="LEFT" style="margin-bottom: 0cm"><br>
</p>
<p align="LEFT" style="margin-bottom: 0cm"><font face="Times New Roman, serif">	</font><span lang="zh-CN">从</span><font face="Times New Roman, serif">printf()</font><span lang="zh-CN">的四个参数入栈过程中我们可以看出：指针</span><font face="Times New Roman, serif">p</font><span lang="zh-CN">的确指向变量</span><font face="Times New Roman, serif">a</font><span lang="zh-CN">了，而变量</span><font face="Times New Roman, serif">a</font><span lang="zh-CN">处的数值也的确被改写成</span><font face="Times New Roman, serif">2</font><span lang="zh-CN">了，</span><font color="#800000"><span lang="zh-CN">问题是：当压入</span><font face="Times New Roman, serif">a</font></font><font color="#800000"><span lang="zh-CN">的值的时候，编译器直接压入了其原始数值</span><font face="Times New Roman, serif">1</font></font><span lang="zh-CN">。</span></p>
<p align="LEFT" style="margin-bottom: 0cm"><font face="Times New Roman, serif">	</font><span lang="zh-CN">关键其实在于：</span><font face="Times New Roman, serif"><font color="#800000">const_cast</font></font><font color="#800000"><span lang="zh-CN">所操作的目标是否为基础数据类型（</span><font face="Times New Roman, serif">char,
int, float, double</font></font><font color="#800000"><span lang="zh-CN">等），如果是类（或结构体）对象则又将是另一番情形</span></font><span lang="zh-CN">。</span></p>
<p lang="zh-CN" align="LEFT" style="margin-bottom: 0cm"><font face="Times New Roman, serif">	</font></p>
<h2 class="cjk">当修改字符串常量</h2>
<p style="margin-bottom: 0cm"><font face="Times New Roman, serif">	</font><span lang="zh-CN">这个问题最早见于一篇文章《</span><font face="Times New Roman, serif">Solmyr</font><span lang="zh-CN">的小品文系列之一：字符串放在哪里？》，在这里我只不过转述一二。</span></p>
<p lang="zh-CN" style="margin-bottom: 0cm"><font face="Times New Roman, serif">	</font>代码如下：</p>
<p style="margin-bottom: 0cm; background: #e6e6e6"><font face="Times New Roman, serif">	<font color="#0000ff"><font size="2" style="font-size: 9pt"><span lang="zxx">void</span></font></font><font color="#000000"><font size="2" style="font-size: 9pt"><span lang="zxx">
</span></font></font><font color="#010001"><font size="2" style="font-size: 9pt"><span lang="zxx">foo</span></font></font><font color="#000000"><font size="2" style="font-size: 9pt"><span lang="zxx">()<br></span></font></font></font><span style="font-family: 'Times New Roman', serif; font-size: 14.4px; ">{<br></span><span style="font-family: 'Times New Roman', serif; "><font color="#0000ff"><font size="2" style="font-size: 9pt"><span lang="zxx">char</span></font></font><font color="#000000"><font size="2" style="font-size: 9pt"><span lang="zxx">*
</span></font></font><font color="#010001"><font size="2" style="font-size: 9pt"><span lang="zxx">str1</span></font></font><font color="#000000"><font size="2" style="font-size: 9pt"><span lang="zxx">			=
</span></font></font><font color="#a31515"><font size="2" style="font-size: 9pt"><span lang="zxx">"watch"</span></font></font><font color="#000000"><font size="2" style="font-size: 9pt"><span lang="zxx">;<br></span></font></font></span><span style="font-family: 'Times New Roman', serif; "><font color="#0000ff"><font size="2" style="font-size: 9pt"><span lang="zxx">const</span></font></font><font color="#000000"><font size="2" style="font-size: 9pt"><span lang="zxx">
</span></font></font><font color="#0000ff"><font size="2" style="font-size: 9pt"><span lang="zxx">char</span></font></font><font color="#000000"><font size="2" style="font-size: 9pt"><span lang="zxx">*
</span></font></font><font color="#010001"><font size="2" style="font-size: 9pt"><span lang="zxx">str2</span></font></font><font color="#000000"><font size="2" style="font-size: 9pt"><span lang="zxx">		=
</span></font></font><font color="#a31515"><font size="2" style="font-size: 9pt"><span lang="zxx">"watch"</span></font></font><font color="#000000"><font size="2" style="font-size: 9pt"><span lang="zxx">;<br></span></font></font></span><span style="font-family: 'Times New Roman', serif; "><font color="#0000ff"><font size="2" style="font-size: 9pt"><span lang="zxx">char</span></font></font><font color="#000000"><font size="2" style="font-size: 9pt"><span lang="zxx">
</span></font></font><font color="#010001"><font size="2" style="font-size: 9pt"><span lang="zxx">str3</span></font></font><font color="#000000"><font size="2" style="font-size: 9pt"><span lang="zxx">[]			=
</span></font></font><font color="#a31515"><font size="2" style="font-size: 9pt"><span lang="zxx">"watch"</span></font></font><font color="#000000"><font size="2" style="font-size: 9pt"><span lang="zxx">;<br><span style="font-size: medium; "><font color="#010001"><font size="2" style="font-size: 9pt"><span lang="zxx"><br>str1</span></font></font><font color="#000000"><font size="2" style="font-size: 9pt"><span lang="zxx">[0]			=
</span></font></font><font color="#a31515"><font size="2" style="font-size: 9pt"><span lang="zxx">'m'</span></font></font><font color="#000000"><font size="2" style="font-size: 9pt"><span lang="zxx">;<br><span style="font-size: medium; "><font color="#010001"><font size="2" style="font-size: 9pt"><span lang="zxx"><font color="#000000"><br></font>std</span></font></font><font color="#000000"><font size="2" style="font-size: 9pt"><span lang="zxx">::</span></font></font><font color="#010001"><font size="2" style="font-size: 9pt"><span lang="zxx">cout</span></font></font><font color="#000000"><font size="2" style="font-size: 9pt"><span lang="zxx">&lt;&lt;
</span></font></font><font color="#010001"><font size="2" style="font-size: 9pt"><span lang="zxx">str1</span></font></font><font color="#000000"><font size="2" style="font-size: 9pt"><span lang="zxx">
&lt;&lt; </span></font></font><font color="#010001"><font size="2" style="font-size: 9pt"><span lang="zxx">std</span></font></font><font color="#000000"><font size="2" style="font-size: 9pt"><span lang="zxx">::</span></font></font><font color="#010001"><font size="2" style="font-size: 9pt"><span lang="zxx">endl</span></font></font><font color="#000000"><font size="2" style="font-size: 9pt"><span lang="zxx">
&lt;&lt; </span></font></font><font color="#010001"><font size="2" style="font-size: 9pt"><span lang="zxx">str2</span></font></font><font color="#000000"><font size="2" style="font-size: 9pt"><span lang="zxx">
&lt;&lt; </span></font></font><font color="#010001"><font size="2" style="font-size: 9pt"><span lang="zxx">std</span></font></font><font color="#000000"><font size="2" style="font-size: 9pt"><span lang="zxx">::</span></font></font><font color="#010001"><font size="2" style="font-size: 9pt"><span lang="zxx">endl</span></font></font><font color="#000000"><font size="2" style="font-size: 9pt"><span lang="zxx">
&lt;&lt; </span></font></font><font color="#010001"><font size="2" style="font-size: 9pt"><span lang="zxx">str3</span></font></font><font color="#000000"><font size="2" style="font-size: 9pt"><span lang="zxx">
&lt;&lt; </span></font></font><font color="#010001"><font size="2" style="font-size: 9pt"><span lang="zxx">std</span></font></font><font color="#000000"><font size="2" style="font-size: 9pt"><span lang="zxx">::</span></font></font><font color="#010001"><font size="2" style="font-size: 9pt"><span lang="zxx">endl</span></font></font><font color="#000000"><font size="2" style="font-size: 9pt"><span lang="zxx">;<br></span></font></font></span></span></font></font></span></span></font></font></span><span style="font-family: 'Times New Roman', serif; font-size: 14.4px; ">}</span></p>
<p lang="zh-CN" align="LEFT" style="margin-bottom: 0cm"><br>
</p>
<p lang="zh-CN" align="LEFT" style="margin-bottom: 0cm"><font face="Times New Roman, serif">	VC6</font>中<font face="Times New Roman, serif">Release</font>版本运行结果如下：</p>
<p lang="zh-CN" align="LEFT" style="margin-bottom: 0cm; background: #e6e6e6">
<font face="Times New Roman, serif">match<br></font><span style="font-family: 'Times New Roman', serif; ">match<br></span><span style="font-family: 'Times New Roman', serif; ">watch</span></p>
<p lang="zh-CN" align="LEFT" style="margin-bottom: 0cm"><font face="Times New Roman, serif">	</font></p>
<p lang="zh-CN" align="LEFT" style="margin-bottom: 0cm"><font face="Times New Roman, serif">	VC2008</font>中<font face="Times New Roman, serif">Release</font>版本运行结果如下：</p>
<p lang="zh-CN" align="LEFT" style="margin-bottom: 0cm; background: #e6e6e6">
<font face="Times New Roman, serif">watch<br></font><span style="font-family: 'Times New Roman', serif; ">watch<br></span><span style="font-family: 'Times New Roman', serif; ">watch</span></p>
<p lang="zh-CN" align="LEFT" style="margin-bottom: 0cm"><br>
</p>
<p lang="zh-CN" align="LEFT" style="margin-bottom: 0cm"><font face="Times New Roman, serif">	</font>容易看出：这段代码的运行结果决定于编译器，因为我们改写了不应该被改写的常量数据。更根本的原因是：由于编译器优化，<font face="Times New Roman, serif"><font color="#800000">str1</font></font><font color="#800000">与<font face="Times New Roman, serif">str2</font></font><font color="#800000">实际上指向的是同一份&#8221;<font face="Times New Roman, serif">watch&#8221;</font></font><font color="#800000">字符串</font>。</p>
<p lang="zh-CN" align="LEFT" style="margin-bottom: 0cm"><font face="Times New Roman, serif">	</font>这还带出了另一件事：<font color="#800000">尽管<font face="Times New Roman, serif">str1</font></font><font color="#800000">的声明中不带<font face="Times New Roman, serif">const</font></font><font color="#800000">，但它所指向的字符串数据隐含是<font face="Times New Roman, serif">const</font></font><font color="#800000">类型的</font>。</p>
<p lang="zh-CN" align="LEFT" style="margin-bottom: 0cm"><font face="Times New Roman, serif">	</font>注意：<font color="#800000">这段代码只有<font face="Times New Roman, serif">Release</font></font><font color="#800000">版本才能顺利执行，<font face="Times New Roman, serif">Debug</font></font><font color="#800000">版版本运行时会得到一个<font face="Times New Roman, serif">Access
violation </font></font>。</p>
<p lang="zh-CN" align="LEFT" style="margin-bottom: 0cm"><br>
</p>
<p lang="zh-CN" align="LEFT" style="margin-bottom: 0cm"><br>
</p>
<p lang="zh-CN" align="LEFT" style="margin-bottom: 0cm"><br></p><img src ="http://www.cppblog.com/xmli/aggbug/134275.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/xmli/" target="_blank">李现民</a> 2010-11-22 15:16 <a href="http://www.cppblog.com/xmli/archive/2010/11/22/134275.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>delete this--对象请求自杀</title><link>http://www.cppblog.com/xmli/archive/2009/08/18/93683.html</link><dc:creator>李现民</dc:creator><author>李现民</author><pubDate>Tue, 18 Aug 2009 03:07:00 GMT</pubDate><guid>http://www.cppblog.com/xmli/archive/2009/08/18/93683.html</guid><wfw:comment>http://www.cppblog.com/xmli/comments/93683.html</wfw:comment><comments>http://www.cppblog.com/xmli/archive/2009/08/18/93683.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/xmli/comments/commentRss/93683.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/xmli/services/trackbacks/93683.html</trackback:ping><description><![CDATA[<meta http-equiv="CONTENT-TYPE" content="text/html; charset=" utf-8="">
<title></title>
<meta name="GENERATOR" content="OpenOffice.org 3.1  (Win32)"><style type="text/css">
<!--
@page { margin: 2cm }
P { margin-bottom: 0.21cm }
-->
</style>
<p style="margin-bottom: 0cm;" align="CENTER"><font color="#000000"><font face="Times New Roman, serif"><font style="font-size: 16pt;" size="4"><strong>delete
this--</strong></font></font><font style="font-size: 16pt;" size="4"><strong><span lang="zh-CN">对象请求自杀</span></strong></font></font></p>
<p style="margin-bottom: 0cm;" align="CENTER">版本：<font face="Times New Roman, serif">0.1</font></p>
<p style="margin-bottom: 0cm;" align="CENTER">最后修改：<font face="Times New Roman, serif">2009-08-18</font></p>
<p style="margin-bottom: 0cm;" align="CENTER">撰写：李现民</p>
<p style="margin-bottom: 0cm;" align="CENTER" lang="zh-CN"><br>
</p>
<p style="margin-bottom: 0cm;" align="LEFT" lang="zh-CN"><font face="Times New Roman, serif">&nbsp;&nbsp;&nbsp;&nbsp;	</font>第一次见<font face="Times New Roman, serif">delete
this</font>的时候，没觉得这是一项会有什么特殊作用的技术，因此也就没有特别关注。</p>
<p style="margin-bottom: 0cm;" align="LEFT" lang="zh-CN"><font face="Times New Roman, serif">&nbsp;&nbsp;&nbsp;&nbsp;	</font>昨日在<font face="Times New Roman, serif">sourcemaking.com</font>上看<font face="Times New Roman, serif">state</font>模式之<font face="Times New Roman, serif">c++</font>实现的时候，看到它在状态转换的时候使用了<font face="Times New Roman, serif">delete
this</font>，感觉似乎还不错。</p>
<p style="margin-bottom: 0cm;" align="LEFT" lang="zh-CN"><font face="Times New Roman, serif">&nbsp;&nbsp;&nbsp;&nbsp;	</font>作为一种&#8220;禁术&#8221;，使用的时候必须要相当小心才行，《<font face="Times New Roman, serif">C++
FAQ</font>》里提到所谓&#8220;小心&#8221;至少包括以下几个方面：</p>
<ol>
    <li>
    <p style="margin-bottom: 0cm;" align="LEFT"><font face="Times New Roman, serif">this</font><span lang="zh-CN">对象是</span><font color="#800000"><span lang="zh-CN">必须是用
    </span><font face="Times New Roman, serif">new</font></font><font color="#800000"><span lang="zh-CN">操作符分配</span></font><span lang="zh-CN">的（而不是用</span><font face="Times New Roman, serif">new[]</font><span lang="zh-CN">，也不是用</span><font face="Times New Roman, serif">placement
    new</font><span lang="zh-CN">，也不是局部对象，也不是</span><font face="Times New Roman, serif">global</font><span lang="zh-CN">对象）；</span></p>
    </li>
    <li>
    <p style="margin-bottom: 0cm;" align="LEFT"><font face="Times New Roman, serif">delete
    this</font><span lang="zh-CN">后，不能访问该对象任何的成员变量及虚函数（</span><font face="Times New Roman, serif">delete
    this</font><span lang="zh-CN">回收的是</span><font color="#800000"><span lang="zh-CN">数据</span></font><span lang="zh-CN">，这包括对象的</span><font color="#800000"><span lang="zh-CN">数据成员以及</span><font face="Times New Roman, serif">vtable</font></font><span lang="zh-CN">，不包括函数代码）；</span></p>
    </li>
    <li>
    <p style="margin-bottom: 0cm;" align="LEFT"><font face="Times New Roman, serif">delete
    this</font><span lang="zh-CN">后，</span><font color="#800000"><span lang="zh-CN">不能再访问</span><font face="Times New Roman, serif">this</font></font><font color="#800000"><span lang="zh-CN">指针</span></font><span lang="zh-CN">。换句话说，你不能去检查它、将它和其他指针比较、和
    </span><font face="Times New Roman, serif">NULL</font><span lang="zh-CN">比较、打印它、转换它，以及其它的任何事情；</span></p>
    </li>
</ol>
<p style="margin-bottom: 0cm;" align="LEFT" lang="zh-CN"><br>
</p>
<p style="margin-bottom: 0cm;" lang="zh-CN"><font face="Times New Roman, serif">&nbsp;&nbsp;&nbsp;&nbsp;	</font>个人认为保证以上禁忌列表基本手段可以包括：</p>
<ol>
    <li>
    <p style="margin-bottom: 0cm;"><span lang="zh-CN">将</span><font color="#800000"><span lang="zh-CN">析构函数私有化</span></font><span lang="zh-CN">（如果有子类，则</span><font face="Times New Roman, serif">protected</font><span lang="zh-CN">化，保证子类能够正确继承）</span><font face="Times New Roman, serif">--</font><span lang="zh-CN">以保证对象必须使用</span><font face="Times New Roman, serif">new</font><span lang="zh-CN">在堆上分配内存；</span></p>
    </li>
    <li>
    <p style="margin-bottom: 0cm;" lang="zh-CN"><font color="#800000">提供（可以在仅仅在基类中）<font face="Times New Roman, serif">Destroy(void)</font></font><font color="#800000">函数</font>，里面仅有一句<font face="Times New Roman, serif">delete
    this--</font>以保证第三方能够将分配的内存回收；</p>
    </li>
</ol>
<p style="margin-bottom: 0cm;" lang="zh-CN"><br>
</p>
<p style="margin-bottom: 0cm;" lang="zh-CN"><font face="Times New Roman, serif">&nbsp;&nbsp;&nbsp;&nbsp;	</font>下一次使用<font face="Times New Roman, serif">state
pattern</font>的时候，我想可以尝试一下。</p><img src ="http://www.cppblog.com/xmli/aggbug/93683.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/xmli/" target="_blank">李现民</a> 2009-08-18 11:07 <a href="http://www.cppblog.com/xmli/archive/2009/08/18/93683.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>给unsigned int 赋一个最大值</title><link>http://www.cppblog.com/xmli/archive/2009/02/06/73117.html</link><dc:creator>李现民</dc:creator><author>李现民</author><pubDate>Fri, 06 Feb 2009 08:37:00 GMT</pubDate><guid>http://www.cppblog.com/xmli/archive/2009/02/06/73117.html</guid><wfw:comment>http://www.cppblog.com/xmli/comments/73117.html</wfw:comment><comments>http://www.cppblog.com/xmli/archive/2009/02/06/73117.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cppblog.com/xmli/comments/commentRss/73117.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/xmli/services/trackbacks/73117.html</trackback:ping><description><![CDATA[
&nbsp;unsigned int，无符号整数，多好的名字，但它的名字与其本身多少有些不符的味道：<br><br>如果 unsigned int a; ，那么，你无法通过测试 if(a&gt;0)测试出你赋给a的值到底是否是正的，因此，通常我们宁愿使用 int b; 配合 assert(a&gt;=0);<br><br>不过，由于项目的需要（基于windows的，使用了太多的DWORD，不过DWORD的定义通常为unsigned long），其中还是使用了一些unsigned int，我发现项目中通常要求赋一个很大（最大）的初始值，用什么？ 0xffffffff嘛？ 我都记不住0x后面应该有几个f，况且，我不能保证系统一定是32位的；<br><br>还是用 unsigned int a= -1;吧，就让无符号整数为自己也做点贡献吧。<br><br><img src ="http://www.cppblog.com/xmli/aggbug/73117.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/xmli/" target="_blank">李现民</a> 2009-02-06 16:37 <a href="http://www.cppblog.com/xmli/archive/2009/02/06/73117.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>std::map于vc6下的使用bug</title><link>http://www.cppblog.com/xmli/archive/2009/02/03/72850.html</link><dc:creator>李现民</dc:creator><author>李现民</author><pubDate>Tue, 03 Feb 2009 02:40:00 GMT</pubDate><guid>http://www.cppblog.com/xmli/archive/2009/02/03/72850.html</guid><wfw:comment>http://www.cppblog.com/xmli/comments/72850.html</wfw:comment><comments>http://www.cppblog.com/xmli/archive/2009/02/03/72850.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.cppblog.com/xmli/comments/commentRss/72850.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/xmli/services/trackbacks/72850.html</trackback:ping><description><![CDATA[&nbsp; 我不想用std::multimap，因为我希望能够使用index随机取得value部分的值，于是便希望定义一个std::map&lt;int, std::vector&lt;int&gt;&gt;的类型，结果在vc6中死活编译不过。我写的测试代码为：std::map&lt;int, std::vector&lt;int&gt;&gt;&nbsp; test_map; 结果报错如下：<br><br>D:\me\document\VC6\test\test.cpp(34) : error C2146: syntax error : missing ',' before identifier 'test_map'<br>D:\me\document\VC6\test\test.cpp(34) : error C2065: 'test_map' : undeclared identifier<br>D:\me\document\VC6\test\test.cpp(34) : error C2143: syntax error : missing '&gt;' before ';'<br><br>&nbsp; 于是改写成如下代码：<br>&nbsp;&nbsp;&nbsp; typedef std::vector&lt;int&gt;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; IntVector;<br>&nbsp;&nbsp;&nbsp; typedef std::map&lt;int, IntVector&gt;&nbsp;&nbsp;&nbsp; IntVectorMap;<br>&nbsp;&nbsp;&nbsp; IntVectorMap test_map;<br><br><br>顺利编译通过 -_- 还真是邪门了。<br><br>注：std::map&lt;int, std::vector&lt;int&gt;&gt;&nbsp; test_map; 在vs2005下顺利编译通过。<br><br><br><br>  <img src ="http://www.cppblog.com/xmli/aggbug/72850.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/xmli/" target="_blank">李现民</a> 2009-02-03 10:40 <a href="http://www.cppblog.com/xmli/archive/2009/02/03/72850.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>通用工厂类（generic factory class）</title><link>http://www.cppblog.com/xmli/archive/2008/10/22/64722.html</link><dc:creator>李现民</dc:creator><author>李现民</author><pubDate>Wed, 22 Oct 2008 10:48:00 GMT</pubDate><guid>http://www.cppblog.com/xmli/archive/2008/10/22/64722.html</guid><wfw:comment>http://www.cppblog.com/xmli/comments/64722.html</wfw:comment><comments>http://www.cppblog.com/xmli/archive/2008/10/22/64722.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cppblog.com/xmli/comments/commentRss/64722.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/xmli/services/trackbacks/64722.html</trackback:ping><description><![CDATA[&nbsp; 旧项目结束，新项目开始，今天开始阅读新项目相关的代码。公司的代码中大量的运用了工厂技术，不过很可惜是simple factory，这样当你新加入一种对象类型的时候都需要去工厂的实现代码（实际上在旧代码实现中还不止如此，乃至于公用父类也需要修改）。这是一件不太好的事情，于是我希望在自己的代码中重新实现，以减少维护量。<br>&nbsp; 我记得《C++对话系列》中有一些相关的讨论，于是我找来查看。非常幸运的，我发现这正是我需要的东西，于是几乎照抄的把代码实现了，代码测试通过。为了符合我自己的阅读习惯，我把其中的一个函数及变量的命名改动了一下：<br>&nbsp; factory.hpp<br>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #000000;"></span><span style="color: #000000;">
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #000000;">#pragma&nbsp;once<br>#pragma&nbsp;warning&nbsp;(disable:</span><span style="color: #000000;">4786</span><span style="color: #000000;">)<br></span><span style="color: #008000;">/*</span><span style="color: #008000;">*******************************************************************<br>created:&nbsp;&nbsp;&nbsp;&nbsp;2008-10-22<br>author:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;lixianmin<br><br>purpose:&nbsp;&nbsp;&nbsp;&nbsp;a&nbsp;generic&nbsp;factory&nbsp;method&nbsp;lib<br>reference:&nbsp;&nbsp;《C++对话系列--Abstract&nbsp;Factory,&nbsp;Template&nbsp;Style》<br>Copyright&nbsp;(C)&nbsp;2008&nbsp;-&nbsp;All&nbsp;Rights&nbsp;Reserved<br>********************************************************************</span><span style="color: #008000;">*/</span><span style="color: #000000;"><br>#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>#include&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">map</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br></span><span style="color: #0000ff;">namespace</span><span style="color: #000000;">&nbsp;lib<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">通用工厂类，根据传入的id创建产品对象</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;template&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">typename&nbsp;BaseType,&nbsp;typename&nbsp;KeyType</span><span style="color: #000000;">=</span><span style="color: #000000;">std::</span><span style="color: #0000ff;">string</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;factory<br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">private</span><span style="color: #000000;">:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;std::auto_ptr</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">BaseType</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;(</span><span style="color: #000000;">*</span><span style="color: #000000;">BaseCreateFunc)();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;std::map</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">KeyType,&nbsp;BaseCreateFunc</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;FuncRegistry;<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">static</span><span style="color: #000000;">&nbsp;factory</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">BaseType,&nbsp;KeyType</span><span style="color: #000000;">&gt;&amp;</span><span style="color: #000000;">&nbsp;get_instance()&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">static&nbsp;singleton，不适用于多线程</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">static</span><span style="color: #000000;">&nbsp;factory</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">BaseType,&nbsp;KeyType</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;obj;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;obj;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;std::auto_ptr</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">BaseType</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;create(</span><span style="color: #0000ff;">const</span><span style="color: #000000;">&nbsp;KeyType</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">&nbsp;id)&nbsp;</span><span style="color: #0000ff;">const</span><span style="color: #000000;"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;std::auto_ptr</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">BaseType</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;obj;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FuncRegistry::const_iterator&nbsp;regEntry&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;_registry.find(id);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(regEntry&nbsp;</span><span style="color: #000000;">!=</span><span style="color: #000000;">&nbsp;_registry.end())&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;obj&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;regEntry</span><span style="color: #000000;">-&gt;</span><span style="color: #000000;">second();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;obj;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;_register_create_function(</span><span style="color: #0000ff;">const</span><span style="color: #000000;">&nbsp;KeyType</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">&nbsp;id,&nbsp;BaseCreateFunc&nbsp;func){_registry[id]&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;func;}<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">private</span><span style="color: #000000;">:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;factory(</span><span style="color: #0000ff;">void</span><span style="color: #000000;">){}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;factory(</span><span style="color: #0000ff;">const</span><span style="color: #000000;">&nbsp;factory</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">&nbsp;other);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;factory&nbsp;</span><span style="color: #0000ff;">operator</span><span style="color: #000000;">=</span><span style="color: #000000;">(</span><span style="color: #0000ff;">const</span><span style="color: #000000;">&nbsp;factory</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">&nbsp;other);<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">private</span><span style="color: #000000;">:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FuncRegistry&nbsp;_registry;<br>&nbsp;&nbsp;&nbsp;&nbsp;};<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">类型(DerivedType)注册类，只要在DerivedType类定义(DerivedType.cpp文件)的最后声明一个&nbsp;lib::factory_register&lt;Base,&nbsp;Derived&gt;&nbsp;reg(id);对象即可</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;template&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">typename&nbsp;BaseType,&nbsp;typename&nbsp;DerivedType,&nbsp;typename&nbsp;KeyType</span><span style="color: #000000;">=</span><span style="color: #000000;">std::</span><span style="color: #0000ff;">string</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;factory_register<br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;factory_register(</span><span style="color: #0000ff;">const</span><span style="color: #000000;">&nbsp;KeyType</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">&nbsp;id)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;factory</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">BaseType,&nbsp;KeyType</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">::get_instance()._register_create_function(id,&nbsp;_create_instance);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">private</span><span style="color: #000000;">:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">static</span><span style="color: #000000;">&nbsp;std::auto_ptr</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">BaseType</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;_create_instance(){</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;std::auto_ptr</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">BaseType</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">(</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;DerivedType);}<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">private</span><span style="color: #000000;">:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;friend&nbsp;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;factory</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">BaseType,&nbsp;KeyType</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">;<br>&nbsp;&nbsp;&nbsp;&nbsp;};<br>}</span></div>
<br></span></div>
测试代码：<br>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; 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;">"</span><span style="color: #000000;">factory.hpp</span><span style="color: #000000;">"</span><span style="color: #000000;"><br></span><span style="color: #008000;">//</span><span style="color: #008000;">基类</span><span style="color: #008000;"><br></span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;Base<br>{<br></span><span style="color: #0000ff;">public</span><span style="color: #000000;">:<br>&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 style="color: #0000ff;">void</span><span style="color: #000000;">)<br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;std::cout</span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;">"</span><span style="color: #000000;">base&nbsp;class</span><span style="color: #000000;">"</span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;">std::endl;<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br>};<br>lib::factory_register</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">Base,&nbsp;Base</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;reg1(</span><span style="color: #000000;">"</span><span style="color: #000000;">base</span><span style="color: #000000;">"</span><span style="color: #000000;">);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">注册Base类型，定义一个file&nbsp;scope的变量，通常应该置于Base.cpp文件结尾<br></span><span style="color: #008000;">//</span><span style="color: #008000;">派生类</span><span style="color: #008000;"><br></span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;Derived:</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;Base<br>{<br></span><span style="color: #0000ff;">public</span><span style="color: #000000;">:<br>&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 style="color: #0000ff;">void</span><span style="color: #000000;">)<br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;std::cout</span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;">"</span><span style="color: #000000;">derived&nbsp;class</span><span style="color: #000000;">"</span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;">std::endl;<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br>};<br>lib::factory_register</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">Base,&nbsp;Derived</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;reg2(</span><span style="color: #000000;">"</span><span style="color: #000000;">derived</span><span style="color: #000000;">"</span><span style="color: #000000;">);&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">注册Derived类型，定义一个file&nbsp;scope的变量，通常应该置于Derived.cpp文件结尾<br><br></span><span style="color: #008000;">//</span><span style="color: #008000;">声明一个全局函数（简化操作，非必需）</span><span style="color: #008000;"><br></span><span style="color: #000000;">lib::factory</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">Base</span><span style="color: #000000;">&gt;&amp;</span><span style="color: #000000;">&nbsp;glb_GetFactory(</span><span style="color: #0000ff;">void</span><span style="color: #000000;">)<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;lib::factory</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">Base</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">::get_instance();<br>}<br></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;">*</span><span style="color: #000000;">&nbsp;argv[])<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;std::auto_ptr</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">Base</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">base</span><span style="color: #000000;">=</span><span style="color: #000000;">glb_GetFactory().create(</span><span style="color: #000000;">"</span><span style="color: #000000;">base</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(</span><span style="color: #0000ff;">base</span><span style="color: #000000;">.</span><span style="color: #0000ff;">get</span><span style="color: #000000;">())<br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">base</span><span style="color: #000000;">-&gt;</span><span style="color: #000000;">print();<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;std::auto_ptr</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">Base</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;derived</span><span style="color: #000000;">=</span><span style="color: #000000;">glb_GetFactory().create(</span><span style="color: #000000;">"</span><span style="color: #000000;">derived</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(derived.</span><span style="color: #0000ff;">get</span><span style="color: #000000;">())<br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;derived</span><span style="color: #000000;">-&gt;</span><span style="color: #000000;">print();<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br><br>&nbsp;&nbsp;&nbsp;&nbsp;system(</span><span style="color: #000000;">"</span><span style="color: #000000;">pause</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br>&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>}</span></div>
输出：<br>base class<br>derived class<br>请按任意键继续. . .<br><br><br><br><br> <img src ="http://www.cppblog.com/xmli/aggbug/64722.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/xmli/" target="_blank">李现民</a> 2008-10-22 18:48 <a href="http://www.cppblog.com/xmli/archive/2008/10/22/64722.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C++中对象生成及使用策略</title><link>http://www.cppblog.com/xmli/archive/2008/10/20/64471.html</link><dc:creator>李现民</dc:creator><author>李现民</author><pubDate>Mon, 20 Oct 2008 02:34:00 GMT</pubDate><guid>http://www.cppblog.com/xmli/archive/2008/10/20/64471.html</guid><wfw:comment>http://www.cppblog.com/xmli/comments/64471.html</wfw:comment><comments>http://www.cppblog.com/xmli/archive/2008/10/20/64471.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/xmli/comments/commentRss/64471.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/xmli/services/trackbacks/64471.html</trackback:ping><description><![CDATA[1、在定义单个数据对象时，如果对象不是特别大(比如某些资源加载的情况)，尽量使用stack对象，避免直接使用new或malloc动态生成对象；<br>2、如果类的成员变量必须是指针对象的话，采用在构造函数中申请(new)并在析构函数中销毁(delete)的办法，避免memory leak；<br>3、定义数组时，使用向量：std::vector&lt;char&gt; vBuffer(nSize)，而不要使用 char* a=new char[nSize];这样可以让容器替你维护这段内存；如果数组大小固定且应用简单的话也可以使用固定长度的数组， 如char text[nSize];<br>4、很多教程都在谈std::auto_ptr的好处，但在我的经验中必须使用std::auto_ptr的地方很少，我只见过两种：一是factory method返回动态对象指针时，为了保证内存释放最好使用智能指针封装；二是加载特别大的资源对象时，这种对象由于太大而不适合放在stack中；<br>5、使用传引用方式传参pass-by-reference(-to-const)，避免使用传指针pass-by-pointer的方式，这样既可以免去指针判NULL的检查，又可以在不失去对象所有权的前提下传递std::auto_ptr&lt;...&gt; 对象<br><br><br><img src ="http://www.cppblog.com/xmli/aggbug/64471.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/xmli/" target="_blank">李现民</a> 2008-10-20 10:34 <a href="http://www.cppblog.com/xmli/archive/2008/10/20/64471.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Memento：ansi文件操作函数</title><link>http://www.cppblog.com/xmli/archive/2008/10/15/64048.html</link><dc:creator>李现民</dc:creator><author>李现民</author><pubDate>Wed, 15 Oct 2008 11:02:00 GMT</pubDate><guid>http://www.cppblog.com/xmli/archive/2008/10/15/64048.html</guid><wfw:comment>http://www.cppblog.com/xmli/comments/64048.html</wfw:comment><comments>http://www.cppblog.com/xmli/archive/2008/10/15/64048.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/xmli/comments/commentRss/64048.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/xmli/services/trackbacks/64048.html</trackback:ping><description><![CDATA[<br>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; 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;">io.h</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;">sys</span><span style="color: #000000;">/</span><span style="color: #000000;">stat.h</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br></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;">*</span><span style="color: #000000;">&nbsp;argv[])<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">const</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">char</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;szPath</span><span style="color: #000000;">=</span><span style="color: #000000;">"</span><span style="color: #000000;">c:\\abc.txt</span><span style="color: #000000;">"</span><span style="color: #000000;">;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(_access(szPath,&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">))&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">测试文件是否存在，如果测试为真，则文件不存在</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;std::cout</span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;">szPath</span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;">"</span><span style="color: #000000;">--does&nbsp;not&nbsp;exist!</span><span style="color: #000000;">"</span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;">std::endl;<br>&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;">-</span><span style="color: #000000;">1</span><span style="color: #000000;">;<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;stat&nbsp;st;<br>&nbsp;&nbsp;&nbsp;&nbsp;stat(szPath,&nbsp;</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">st);<br>&nbsp;&nbsp;&nbsp;&nbsp;std::cout</span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;">"</span><span style="color: #000000;">file&nbsp;size=</span><span style="color: #000000;">"</span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;">st.st_size</span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;">std::endl;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">获取文件属性(包括大小、创建时间、宿主等等)</span><span style="color: #008000;"><br></span><span style="color: #000000;"><br>&nbsp;&nbsp;&nbsp;&nbsp;system(</span><span style="color: #000000;">"</span><span style="color: #000000;">pause</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br>&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>}</span></div>
<br><img src ="http://www.cppblog.com/xmli/aggbug/64048.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/xmli/" target="_blank">李现民</a> 2008-10-15 19:02 <a href="http://www.cppblog.com/xmli/archive/2008/10/15/64048.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>datastream, C++数据序列化与反序列化容器</title><link>http://www.cppblog.com/xmli/archive/2008/10/15/64030.html</link><dc:creator>李现民</dc:creator><author>李现民</author><pubDate>Wed, 15 Oct 2008 06:55:00 GMT</pubDate><guid>http://www.cppblog.com/xmli/archive/2008/10/15/64030.html</guid><wfw:comment>http://www.cppblog.com/xmli/comments/64030.html</wfw:comment><comments>http://www.cppblog.com/xmli/archive/2008/10/15/64030.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/xmli/comments/commentRss/64030.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/xmli/services/trackbacks/64030.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &nbsp; 其实本来不想自己写这样一个类的，但找来找去都没有找到符合生活习惯的，于是在经过反复的推敲设计后，呜，我终于承认自己功力不够---无法将内存管理与迭代器完美地结合在一起，只好只好先用std::vector了，于是便有了下面的代码。到目前为止还不能号称功能完善，但，但应该基本可用了，堪堪记在这里，也许能给以后的自己一些帮助，或可得到高手指点一二：&nbsp; 类文件被保存为datastr...&nbsp;&nbsp;<a href='http://www.cppblog.com/xmli/archive/2008/10/15/64030.html'>阅读全文</a><img src ="http://www.cppblog.com/xmli/aggbug/64030.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/xmli/" target="_blank">李现民</a> 2008-10-15 14:55 <a href="http://www.cppblog.com/xmli/archive/2008/10/15/64030.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>enum与对象状态检查</title><link>http://www.cppblog.com/xmli/archive/2008/09/27/62883.html</link><dc:creator>李现民</dc:creator><author>李现民</author><pubDate>Sat, 27 Sep 2008 03:44:00 GMT</pubDate><guid>http://www.cppblog.com/xmli/archive/2008/09/27/62883.html</guid><wfw:comment>http://www.cppblog.com/xmli/comments/62883.html</wfw:comment><comments>http://www.cppblog.com/xmli/archive/2008/09/27/62883.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/xmli/comments/commentRss/62883.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/xmli/services/trackbacks/62883.html</trackback:ping><description><![CDATA[　　对class成员函数而言，特别是public成员函数，在函数的入口处往往会有一大段if()语句进行参数有效性检查，(对应该的，对private成员函数，我更喜欢用assert)。除此之外，class对象也经常会拥有一定的状态，并某几个状态之间进行不断的切换，而class的成员函数也往往只会在对象牌某种状态下调用才是有效的，因此对这样的类函数，除参数检查外，状态检查也是必要的。<br>　　比如对录音机Recorder这样一个类而言，至少会有几个状态：数据加载Loading，数据保存Saving，数据加载完毕Loaded，数据录制Recording，数据播放Playing等等，这些状态往往是互斥的(但并不总是这样)，对Play()函数，必须Loaded=true，对Save函数，必须Recording=false<br>　　状态检测的必要性在于：代码的扩大(复杂化)，新人参与的维护及状态的更迭随时有可能在出人意料的情况下调用到某些函数，这些函数可能在大多数情况下在这里调用是有意义的，但在某些极端的情况下却可能造成数据破坏，因此在各函数入口处执行完善的状态检测是很有意义的。<br>　　针对各种状态可以维护一个对应的bool值，但写一个enum附带一个status数组可能更容易维护：<br>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">enum</span><span style="color: #000000;"><br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;stLoaded,&nbsp;&nbsp;&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;">数据加载完毕</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;stRecording,&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;">数据录制中</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;stReplaying,&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;">回放中</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;stSize&nbsp;&nbsp;&nbsp;&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;">状态数组的大小</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;};<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">bool</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;m_aStatus[stSize];</span></div>
&nbsp;&nbsp; OK，这时可以在构造函数中执行std::fill(m_aStatus, m_aStatus+stSize, false);对所有的状态进行初始化，特别是：你随后可以任意地增减这个enum中状态变量的数目或改动其名称，同时均不需要担心状态变量初始化问题<br><br> <img src ="http://www.cppblog.com/xmli/aggbug/62883.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/xmli/" target="_blank">李现民</a> 2008-09-27 11:44 <a href="http://www.cppblog.com/xmli/archive/2008/09/27/62883.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>不要在C++的.h文件中给出全局函数的定义式</title><link>http://www.cppblog.com/xmli/archive/2008/09/23/62595.html</link><dc:creator>李现民</dc:creator><author>李现民</author><pubDate>Tue, 23 Sep 2008 07:41:00 GMT</pubDate><guid>http://www.cppblog.com/xmli/archive/2008/09/23/62595.html</guid><wfw:comment>http://www.cppblog.com/xmli/comments/62595.html</wfw:comment><comments>http://www.cppblog.com/xmli/archive/2008/09/23/62595.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cppblog.com/xmli/comments/commentRss/62595.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/xmli/services/trackbacks/62595.html</trackback:ping><description><![CDATA[　　本来，是理所当然的想设计成inline函数的，编译也没有问题，但在链接的时候报error LNK2005的错误（＊＊函数已经在＊＊.obj文件中定义。。。），结果证明，是因为我把定义式写在了.h文件中。<br>　　把定义式放到.cpp文件中，在.h文件中仅仅保留全局函数的定义式，链接通过<br>　　可是，这样的函数是inline的嘛？在定义式那边加上inline?待进一步探索<br><br><img src ="http://www.cppblog.com/xmli/aggbug/62595.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/xmli/" target="_blank">李现民</a> 2008-09-23 15:41 <a href="http://www.cppblog.com/xmli/archive/2008/09/23/62595.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>const对象只能调用const成员函数</title><link>http://www.cppblog.com/xmli/archive/2008/09/09/61359.html</link><dc:creator>李现民</dc:creator><author>李现民</author><pubDate>Tue, 09 Sep 2008 01:47:00 GMT</pubDate><guid>http://www.cppblog.com/xmli/archive/2008/09/09/61359.html</guid><wfw:comment>http://www.cppblog.com/xmli/comments/61359.html</wfw:comment><comments>http://www.cppblog.com/xmli/archive/2008/09/09/61359.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/xmli/comments/commentRss/61359.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/xmli/services/trackbacks/61359.html</trackback:ping><description><![CDATA[&nbsp;&nbsp; 这一点以前一直没有太注意，一直没有尽心去把成员函数写成const的，《effective c++》里有一条&#8220;宁以pass by reference to const替换pass by value&#8221;，在遵循这条原则的前提下，你在函数内部碰到的很可能是const对象，因此，如果你的成员函数不是const成员函数的话，那么，只能const_cast了<br>&nbsp;&nbsp; 以后注意<br><img src ="http://www.cppblog.com/xmli/aggbug/61359.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/xmli/" target="_blank">李现民</a> 2008-09-09 09:47 <a href="http://www.cppblog.com/xmli/archive/2008/09/09/61359.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C++中std::set&lt;&gt;集合中元素比较器（less&lt;&gt;）的设计</title><link>http://www.cppblog.com/xmli/archive/2008/09/08/61282.html</link><dc:creator>李现民</dc:creator><author>李现民</author><pubDate>Mon, 08 Sep 2008 01:44:00 GMT</pubDate><guid>http://www.cppblog.com/xmli/archive/2008/09/08/61282.html</guid><wfw:comment>http://www.cppblog.com/xmli/comments/61282.html</wfw:comment><comments>http://www.cppblog.com/xmli/archive/2008/09/08/61282.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/xmli/comments/commentRss/61282.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/xmli/services/trackbacks/61282.html</trackback:ping><description><![CDATA[&nbsp;&nbsp; 一直没有总结过，每次设计都会出一些问题，要知道STL的报错可不是那么容易看懂的。<br>&nbsp;&nbsp; 假定需要设计的类为Country，各country之类比较的依据是人口population，分析如下：<br><br>&nbsp;&nbsp; 情形一：如果类Country类是你本人设计的，即你拥有对Country类的修改权，那么在类中重载operator&lt;就可以了，需要注意的就是必须将其设计为const成员函数，如下：<br>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;Country<br>{<br></span><span style="color: #0000ff;">public</span><span style="color: #000000;">:<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">explicit</span><span style="color: #000000;">&nbsp;Country(</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;population)<br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;m_nPopulation</span><span style="color: #000000;">=</span><span style="color: #000000;">population;<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;print()<br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;std::cout</span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;">m_nPopulation</span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;">std::endl;<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">注：operator&lt;必须是const成员函数</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">bool</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">operator</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">(</span><span style="color: #0000ff;">const</span><span style="color: #000000;">&nbsp;Country</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">&nbsp;b)</span><span style="color: #0000ff;">const</span><span style="color: #000000;"><br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;m_nPopulation</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">b.m_nPopulation;<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br><br></span><span style="color: #0000ff;">private</span><span style="color: #000000;">:<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;m_nPopulation;<br>};<br></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;">*</span><span style="color: #000000;">&nbsp;argv[])<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;Country&nbsp;countryArray[]</span><span style="color: #000000;">=</span><span style="color: #000000;">{Country(</span><span style="color: #000000;">43</span><span style="color: #000000;">),&nbsp;Country(</span><span style="color: #000000;">54</span><span style="color: #000000;">),Country(</span><span style="color: #000000;">85</span><span style="color: #000000;">),Country(</span><span style="color: #000000;">95</span><span style="color: #000000;">),Country(</span><span style="color: #000000;">12</span><span style="color: #000000;">),Country(</span><span style="color: #000000;">57</span><span style="color: #000000;">),Country(</span><span style="color: #000000;">124</span><span style="color: #000000;">),Country(</span><span style="color: #000000;">78</span><span style="color: #000000;">),<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Country(</span><span style="color: #000000;">45</span><span style="color: #000000;">),&nbsp;Country(</span><span style="color: #000000;">56</span><span style="color: #000000;">),Country(</span><span style="color: #000000;">87</span><span style="color: #000000;">),Country(</span><span style="color: #000000;">457</span><span style="color: #000000;">),Country(</span><span style="color: #000000;">567</span><span style="color: #000000;">),Country(</span><span style="color: #000000;">123</span><span style="color: #000000;">),Country(</span><span style="color: #000000;">456</span><span style="color: #000000;">),Country(</span><span style="color: #000000;">237</span><span style="color: #000000;">),<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Country(</span><span style="color: #000000;">43</span><span style="color: #000000;">),&nbsp;Country(</span><span style="color: #000000;">784</span><span style="color: #000000;">),Country(</span><span style="color: #000000;">728</span><span style="color: #000000;">),Country(</span><span style="color: #000000;">76</span><span style="color: #000000;">),Country(</span><span style="color: #000000;">467</span><span style="color: #000000;">),Country(</span><span style="color: #000000;">83</span><span style="color: #000000;">),Country(</span><span style="color: #000000;">723</span><span style="color: #000000;">),Country(</span><span style="color: #000000;">86</span><span style="color: #000000;">)};<br>&nbsp;&nbsp;&nbsp;&nbsp;std::</span><span style="color: #0000ff;">set</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">Country</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;countrySet;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;nSize</span><span style="color: #000000;">=</span><span style="color: #0000ff;">sizeof</span><span style="color: #000000;">&nbsp;countryArray</span><span style="color: #000000;">/</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">sizeof</span><span style="color: #000000;">&nbsp;countryArray[</span><span style="color: #000000;">0</span><span style="color: #000000;">];<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">for</span><span style="color: #000000;">&nbsp;(</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;i</span><span style="color: #000000;">=</span><span style="color: #000000;">0</span><span style="color: #000000;">;&nbsp;i</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">nSize;&nbsp;</span><span style="color: #000000;">++</span><span style="color: #000000;">i)<br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;countrySet.insert(countryArray[i]);<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">for</span><span style="color: #000000;">&nbsp;(std::</span><span style="color: #0000ff;">set</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">Country</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">::iterator&nbsp;iter</span><span style="color: #000000;">=</span><span style="color: #000000;">countrySet.begin();&nbsp;countrySet.end()</span><span style="color: #000000;">!=</span><span style="color: #000000;">iter;&nbsp;</span><span style="color: #000000;">++</span><span style="color: #000000;">iter)<br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;iter</span><span style="color: #000000;">-&gt;</span><span style="color: #000000;">print();<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br><br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">Sleep(int(2e9));</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;system(</span><span style="color: #000000;">"</span><span style="color: #000000;">pause</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br>&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>}<br></span></div>
<br>&nbsp;&nbsp; 情形二：Country为不是你设计的，即类中没有已存在的operator&lt;比较器，同时你也无法对其进行修改，那么你现在需要做的是在外部设计一个比较器，确切的说，是一个函数对象（或函数，但函数无法内联），如下：<br><br>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;Country<br>{<br></span><span style="color: #0000ff;">public</span><span style="color: #000000;">:<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">explicit</span><span style="color: #000000;">&nbsp;Country(</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;population)<br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;m_nPopulation</span><span style="color: #000000;">=</span><span style="color: #000000;">population;<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;print()<br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;std::cout</span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;">m_nPopulation</span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;">std::endl;<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">比上一个设计需要新加入一个函数</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;GetPopulation(</span><span style="color: #0000ff;">void</span><span style="color: #000000;">)&nbsp;</span><span style="color: #0000ff;">const</span><span style="color: #000000;"><br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;m_nPopulation;<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br></span><span style="color: #0000ff;">private</span><span style="color: #000000;">:<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;m_nPopulation;<br>};<br></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;">*</span><span style="color: #000000;">&nbsp;argv[])<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;Country&nbsp;countryArray[]</span><span style="color: #000000;">=</span><span style="color: #000000;">{Country(</span><span style="color: #000000;">43</span><span style="color: #000000;">),&nbsp;Country(</span><span style="color: #000000;">54</span><span style="color: #000000;">),Country(</span><span style="color: #000000;">85</span><span style="color: #000000;">),Country(</span><span style="color: #000000;">95</span><span style="color: #000000;">),Country(</span><span style="color: #000000;">12</span><span style="color: #000000;">),Country(</span><span style="color: #000000;">57</span><span style="color: #000000;">),Country(</span><span style="color: #000000;">124</span><span style="color: #000000;">),Country(</span><span style="color: #000000;">78</span><span style="color: #000000;">),<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Country(</span><span style="color: #000000;">45</span><span style="color: #000000;">),&nbsp;Country(</span><span style="color: #000000;">56</span><span style="color: #000000;">),Country(</span><span style="color: #000000;">87</span><span style="color: #000000;">),Country(</span><span style="color: #000000;">457</span><span style="color: #000000;">),Country(</span><span style="color: #000000;">567</span><span style="color: #000000;">),Country(</span><span style="color: #000000;">123</span><span style="color: #000000;">),Country(</span><span style="color: #000000;">456</span><span style="color: #000000;">),Country(</span><span style="color: #000000;">237</span><span style="color: #000000;">),<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Country(</span><span style="color: #000000;">43</span><span style="color: #000000;">),&nbsp;Country(</span><span style="color: #000000;">784</span><span style="color: #000000;">),Country(</span><span style="color: #000000;">728</span><span style="color: #000000;">),Country(</span><span style="color: #000000;">76</span><span style="color: #000000;">),Country(</span><span style="color: #000000;">467</span><span style="color: #000000;">),Country(</span><span style="color: #000000;">83</span><span style="color: #000000;">),Country(</span><span style="color: #000000;">723</span><span style="color: #000000;">),Country(</span><span style="color: #000000;">86</span><span style="color: #000000;">)};<br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">设计函数对象</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;country_less:</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;std::binary_function</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">Country,&nbsp;Country,&nbsp;</span><span style="color: #0000ff;">bool</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">这个倒不必须成为const成员函数，呵呵</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">bool</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">operator</span><span style="color: #000000;">()(</span><span style="color: #0000ff;">const</span><span style="color: #000000;">&nbsp;Country</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">&nbsp;a,&nbsp;</span><span style="color: #0000ff;">const</span><span style="color: #000000;">&nbsp;Country</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">&nbsp;b)</span><span style="color: #0000ff;">const</span><span style="color: #000000;"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;a.GetPopulation()</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">b.GetPopulation();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;};<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">std::set的定义就要复杂一些了</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;std::</span><span style="color: #0000ff;">set</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">Country,&nbsp;country_less</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;countrySet;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;nSize</span><span style="color: #000000;">=</span><span style="color: #0000ff;">sizeof</span><span style="color: #000000;">&nbsp;countryArray</span><span style="color: #000000;">/</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">sizeof</span><span style="color: #000000;">&nbsp;countryArray[</span><span style="color: #000000;">0</span><span style="color: #000000;">];<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">for</span><span style="color: #000000;">&nbsp;(</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;i</span><span style="color: #000000;">=</span><span style="color: #000000;">0</span><span style="color: #000000;">;&nbsp;i</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">nSize;&nbsp;</span><span style="color: #000000;">++</span><span style="color: #000000;">i)<br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;countrySet.insert(countryArray[i]);<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">同样，迭代器的定义也要复杂一些</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">for</span><span style="color: #000000;">&nbsp;(std::</span><span style="color: #0000ff;">set</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">Country,&nbsp;country_less</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">::iterator&nbsp;iter</span><span style="color: #000000;">=</span><span style="color: #000000;">countrySet.begin();&nbsp;countrySet.end()</span><span style="color: #000000;">!=</span><span style="color: #000000;">iter;&nbsp;</span><span style="color: #000000;">++</span><span style="color: #000000;">iter)<br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;iter</span><span style="color: #000000;">-&gt;</span><span style="color: #000000;">print();<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">Sleep(int(2e9));</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;system(</span><span style="color: #000000;">"</span><span style="color: #000000;">pause</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br>&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>}</span></div>
<br>&nbsp;&nbsp; 这两种情况的作用就是std::less&lt;&gt;谓词，因此同样适用于std::sort()<br><br><br><br><br><br><br><br><br><br><img src ="http://www.cppblog.com/xmli/aggbug/61282.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/xmli/" target="_blank">李现民</a> 2008-09-08 09:44 <a href="http://www.cppblog.com/xmli/archive/2008/09/08/61282.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>char, wchar_t与STL的字符串格式化format</title><link>http://www.cppblog.com/xmli/archive/2008/09/02/60663.html</link><dc:creator>李现民</dc:creator><author>李现民</author><pubDate>Tue, 02 Sep 2008 02:23:00 GMT</pubDate><guid>http://www.cppblog.com/xmli/archive/2008/09/02/60663.html</guid><wfw:comment>http://www.cppblog.com/xmli/comments/60663.html</wfw:comment><comments>http://www.cppblog.com/xmli/archive/2008/09/02/60663.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cppblog.com/xmli/comments/commentRss/60663.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/xmli/services/trackbacks/60663.html</trackback:ping><description><![CDATA[<br>&nbsp;&nbsp; 最近一直在写序列化类，希望把一些游戏过程中的场景数据信息存储到硬盘。因为需要处理的数据很多，所以我写了一个工具类，其中包括字符串的序列化，问题来了：<br>&nbsp;&nbsp; 公司原先的代码参差不齐，有使用AString的（使用ANSI char作为字符单元，相当于std::string），也有考虑到unicode问题而采用AWString的（使用wchar_t作为字符单元，相当于std::wstring），同时考虑到根据编译环境自动视别的问题，也定义有一个宏ACString，即：如果定义有UNICODE环境变量，则自动替换为AWString，否则使用AString。好吧，自作聪明的我使用了ACString来写工具函数，测试时没有任何问题，但一旦加入到真正的运行环境中就会出现&#8220;把const char*转化为bool，性能警告&#8221;的错误，几经检查，发现在游戏环境下，传入的参数是AString类型，而我用的ACString则被自动转化成了AWString，找不到参数匹配的，所以只有默认转化了。<br>&nbsp;&nbsp; 看来，解决办法只能是同时提供AString与AWString两种类型的工具函数，因为你不知道你的客户传给你的将是哪一种，除非大家都铁了心的一致使用ACString，然而在现实的编码中，这却是不切实际的。<br>&nbsp;&nbsp; 这让我想起前两天为STL写的格式化函数（STL没有，只好自己写了-_-），当时我也想自作聪明的把std::string与std::wstring合二为一，现在想来恐怕是庸人自扰罢了，于是早上起来把原来的代码作下修改，如下：<br>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; 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;">stdarg.h</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br>#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>#include&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">vector</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;">cassert</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br><br>#ifndef&nbsp;__STR_STR_HPP_INCLUDED_<br></span><span style="color: #0000ff;">#define</span><span style="color: #000000;">&nbsp;__STR_STR_HPP_INCLUDED_</span><span style="color: #000000;"><br></span><span style="color: #0000ff;">namespace</span><span style="color: #000000;">&nbsp;str<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">字符串格式化函数</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;std::</span><span style="color: #0000ff;">string</span><span style="color: #000000;">&nbsp;format(</span><span style="color: #0000ff;">const</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">char</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">fmt,&nbsp;<img src="http://www.cppblog.com/Images/dot.gif">)&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;std::</span><span style="color: #0000ff;">string</span><span style="color: #000000;">&nbsp;strResult</span><span style="color: #000000;">=</span><span style="color: #000000;">""</span><span style="color: #000000;">;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(NULL&nbsp;</span><span style="color: #000000;">!=</span><span style="color: #000000;">&nbsp;fmt)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;va_list&nbsp;marker&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;NULL;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;va_start(marker,&nbsp;fmt);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">初始化变量参数&nbsp;</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;size_t&nbsp;nLength&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;_vscprintf(fmt,&nbsp;marker)&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">1</span><span style="color: #000000;">;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">获取格式化字符串长度</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;std::vector</span><span style="color: #000000;">&lt;</span><span style="color: #0000ff;">char</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;vBuffer(nLength,&nbsp;</span><span style="color: #000000;">'</span><span style="color: #000000;">\0</span><span style="color: #000000;">'</span><span style="color: #000000;">);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">创建用于存储格式化字符串的字符数组</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;nWritten&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;_vsnprintf_s(</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">vBuffer[</span><span style="color: #000000;">0</span><span style="color: #000000;">],&nbsp;vBuffer.size(),&nbsp;nLength,&nbsp;fmt,&nbsp;marker);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(nWritten</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">0</span><span style="color: #000000;">)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;strResult&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">vBuffer[</span><span style="color: #000000;">0</span><span style="color: #000000;">];<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;va_end(marker);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">重置变量参数</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;strResult;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">字符串格式化函数</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;std::wstring&nbsp;format(</span><span style="color: #0000ff;">const</span><span style="color: #000000;">&nbsp;wchar_t&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">fmt,&nbsp;<img src="http://www.cppblog.com/Images/dot.gif">)&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;std::wstring&nbsp;strResult</span><span style="color: #000000;">=</span><span style="color: #000000;">L</span><span style="color: #000000;">""</span><span style="color: #000000;">;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(NULL&nbsp;</span><span style="color: #000000;">!=</span><span style="color: #000000;">&nbsp;fmt)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;va_list&nbsp;marker&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;NULL;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;va_start(marker,&nbsp;fmt);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">初始化变量参数</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;size_t&nbsp;nLength&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;_vscwprintf(fmt,&nbsp;marker)&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">1</span><span style="color: #000000;">;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">获取格式化字符串长度</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;std::vector</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">wchar_t</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;vBuffer(nLength,&nbsp;L</span><span style="color: #000000;">'</span><span style="color: #000000;">\0</span><span style="color: #000000;">'</span><span style="color: #000000;">);&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">创建用于存储格式化字符串的字符数组</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;nWritten&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;_vsnwprintf_s(</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">vBuffer[</span><span style="color: #000000;">0</span><span style="color: #000000;">],&nbsp;vBuffer.size(),&nbsp;nLength,&nbsp;fmt,&nbsp;marker);&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(nWritten&nbsp;</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;strResult&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">vBuffer[</span><span style="color: #000000;">0</span><span style="color: #000000;">];<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;va_end(marker);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">重置变量参数</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;strResult;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<br>}<br></span><span style="color: #0000ff;">#endif</span><span style="color: #000000;"><br></span></div>
测试全码（其中str.hpp就是上面代码的文件名了）：<br>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; 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;">cassert</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br>#include&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">str.hpp</span><span style="color: #000000;">"</span><span style="color: #000000;"><br></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;">*</span><span style="color: #000000;">&nbsp;argv[])<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">const</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">double</span><span style="color: #000000;">&nbsp;PI</span><span style="color: #000000;">=</span><span style="color: #000000;">3.1415926</span><span style="color: #000000;">;<br>&nbsp;&nbsp;&nbsp;&nbsp;std::</span><span style="color: #0000ff;">string</span><span style="color: #000000;">&nbsp;s</span><span style="color: #000000;">=</span><span style="color: #000000;">str::format(</span><span style="color: #000000;">"</span><span style="color: #000000;">ANSI%s---字符：%c；整数：%d；双精度：%f</span><span style="color: #000000;">"</span><span style="color: #000000;">,&nbsp;</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;">'</span><span style="color: #000000;">a</span><span style="color: #000000;">'</span><span style="color: #000000;">,&nbsp;</span><span style="color: #000000;">38</span><span style="color: #000000;">,&nbsp;PI);<br>&nbsp;&nbsp;&nbsp;&nbsp;std::cout</span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;">s</span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;">std::endl;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;std::wstring&nbsp;ws</span><span style="color: #000000;">=</span><span style="color: #000000;">str::format(L</span><span style="color: #000000;">"</span><span style="color: #000000;">UNICODE%s---字符：%c；整数：%d；双精度：%f</span><span style="color: #000000;">"</span><span style="color: #000000;">,&nbsp;L</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;">'</span><span style="color: #000000;">u</span><span style="color: #000000;">'</span><span style="color: #000000;">,&nbsp;</span><span style="color: #000000;">83</span><span style="color: #000000;">,&nbsp;PI);<br>&nbsp;&nbsp;&nbsp;&nbsp;std::wcout</span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;">ws</span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;">std::endl;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;system(</span><span style="color: #000000;">"</span><span style="color: #000000;">pause</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br>&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>}</span></div>
输出结果：<br><img src="http://www.cppblog.com/images/cppblog_com/xmli/2008-09-02.JPG" border="0"><br>&nbsp;&nbsp; 问题一：前面的format函数只能在vs2005下通过编译，在vc6.0下就不可以，原因是<img src="file:///C:/DOCUME~1/DevUser/LOCALS~1/Temp/moz-screenshot.jpg" alt="">用于&#8220;获取格式化字符串长度&#8221;的_vscprintf和_vscwprintf在vc6.0中找不到替代品；<br>&nbsp;&nbsp; 问题二：相信大家已经看到了，ANSI字符串的测试没有任何问题，但UNICODE字符串在输出时中断了，确切的说是在输出到中文时中断了，我用断点查看过，ws的构造没有问题，即wchar_t版的format函数没有问题，那么问题就应该出在std::wcout上面，但问题在哪呢？<br>&nbsp;&nbsp; 诸位看官，欢迎提供任何指导意见。<br><br><br><br><br><br><img src ="http://www.cppblog.com/xmli/aggbug/60663.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/xmli/" target="_blank">李现民</a> 2008-09-02 10:23 <a href="http://www.cppblog.com/xmli/archive/2008/09/02/60663.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>