<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Wut I am &#187; c++</title>
	<atom:link href="http://wutiam.net/tag/cpp/feed/" rel="self" type="application/rss+xml" />
	<link>http://wutiam.net</link>
	<description>I'm islet8, I'm what I am</description>
	<lastBuildDate>Wed, 28 Jul 2010 02:50:02 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>避免在 C++ 类结构中出现私有虚成员函数</title>
		<link>http://wutiam.net/2010/07/avoid-private-virtual-member-function-in-cpp-class/</link>
		<comments>http://wutiam.net/2010/07/avoid-private-virtual-member-function-in-cpp-class/#comments</comments>
		<pubDate>Tue, 27 Jul 2010 12:34:44 +0000</pubDate>
		<dc:creator>islet8</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[c++]]></category>

		<guid isPermaLink="false">http://wutiam.net/?p=134</guid>
		<description><![CDATA[最近在重构 C++ 代码时突然想起，如果一个基类的虚成员函数被设为 private，有没有意义？又是否合理？
当然，有其一定的意义，那就是不希望子类在其他地方调用父类的这个函数，包括在子类的实现中；如果需要这个功能，应该使用其 public 的接口去使用该功能。而子类可以提供自己的实现，以提供多态。但是，如果子类觉得需要，还可以把这个 private 的虚成员函数重定义成 protected（虽然这会让人迷惑），从而使子类的子类们调用它。
有同学可能会问，如果是一个 private 的纯虚成员函数（语法上当然合理），那语义合理么？嗯，我觉得这的确是个问题——也许是为了告诉写子类的其他同学，这个虚函数，我不希望你们在除了基类已有的接口里调用之外还来用——仅仅是一个道德约束？！
嗯，C++ 就是灵活得过头了，什么都让程序员自己去把控，可是别忘了，“太多的选择比没有选择糟糕得多”。所以，我决定，为了自己也为了别人不犯迷糊，避免使用 private 的虚函数，private 的成员函数仅包含当前类自己使用的函数。
BTW，类的成员变量正好相反，能设为 private 的尽量不要 protected 更不要public，否则后期维护，嗯嗯，就太痛苦了。


Related posts:乱用 STL 是地狱
do...while(0) 的妙用
让 C++ 的 new 操作失败时返回空指针



Related posts:<ul><li><a href='http://wutiam.net/2010/04/stl-on-the-wrong-way-may-lead-to-hell/' rel='bookmark' title='Permanent Link: 乱用 STL 是地狱'>乱用 STL 是地狱</a></li>
<li><a href='http://wutiam.net/2010/03/ingenious-usage-of-do-while-0/' rel='bookmark' title='Permanent Link: do...while(0) 的妙用'>do...while(0) 的妙用</a></li>
<li><a href='http://wutiam.net/2010/02/let-cpp-new-operator-return-null-when-failed/' rel='bookmark' title='Permanent Link: 让 C++ 的 new 操作失败时返回空指针'>让 C++ 的 new 操作失败时返回空指针</a></li>
</ul>]]></description>
			<content:encoded><![CDATA[<p>最近在重构 C++ 代码时突然想起，如果一个基类的虚成员函数被设为 private，有没有意义？又是否合理？</p>
<p>当然，有其一定的意义，那就是不希望子类在其他地方调用父类的这个函数，包括在子类的实现中；如果需要这个功能，应该使用其 public 的接口去使用该功能。而子类可以提供自己的实现，以提供多态。但是，如果子类觉得需要，还可以把这个 private 的虚成员函数重定义成 protected（虽然这会让人迷惑），从而使子类的子类们调用它。</p>
<p>有同学可能会问，如果是一个 private 的纯虚成员函数（语法上当然合理），那语义合理么？嗯，我觉得这的确是个问题——也许是为了告诉写子类的其他同学，这个虚函数，我不希望你们在除了基类已有的接口里调用之外还来用——仅仅是一个道德约束？！</p>
<p>嗯，C++ 就是灵活得过头了，什么都让程序员自己去把控，可是别忘了，“太多的选择比没有选择糟糕得多”。所以，我决定，为了自己也为了别人不犯迷糊，避免使用 private 的虚函数，private 的成员函数仅包含当前类自己使用的函数。</p>
<p>BTW，类的成员变量正好相反，能设为 private 的尽量不要 protected 更不要public，否则后期维护，嗯嗯，就太痛苦了。</p>


<p>Related posts:<ul><li><a href='http://wutiam.net/2010/04/stl-on-the-wrong-way-may-lead-to-hell/' rel='bookmark' title='Permanent Link: 乱用 STL 是地狱'>乱用 STL 是地狱</a></li>
<li><a href='http://wutiam.net/2010/03/ingenious-usage-of-do-while-0/' rel='bookmark' title='Permanent Link: do...while(0) 的妙用'>do...while(0) 的妙用</a></li>
<li><a href='http://wutiam.net/2010/02/let-cpp-new-operator-return-null-when-failed/' rel='bookmark' title='Permanent Link: 让 C++ 的 new 操作失败时返回空指针'>让 C++ 的 new 操作失败时返回空指针</a></li>
</ul></p>]]></content:encoded>
			<wfw:commentRss>http://wutiam.net/2010/07/avoid-private-virtual-member-function-in-cpp-class/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>乱用 STL 是地狱</title>
		<link>http://wutiam.net/2010/04/stl-on-the-wrong-way-may-lead-to-hell/</link>
		<comments>http://wutiam.net/2010/04/stl-on-the-wrong-way-may-lead-to-hell/#comments</comments>
		<pubDate>Mon, 19 Apr 2010 05:43:21 +0000</pubDate>
		<dc:creator>islet8</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[c++]]></category>
		<category><![CDATA[stl]]></category>

		<guid isPermaLink="false">http://wutiam.net/?p=128</guid>
		<description><![CDATA[根据《Effective STL》条款21中的例子，建立一个比较类型为 less_equal 的 set 容器：

    set&#60; int, less_equal&#60;int&#62; &#62; s;

然后连续插入两个10：

    s.insert&#40;10&#41;; // 10a
    s.insert&#40;10&#41;; // 10b

会得到什么？
在debug下，可能会给出一个assert报比较符号不合法，第二次插入失败，但在release下，这个动作很可能是未定义的，而通常的结果是，set中存在了两个键值同为10的项，也就是说，set被悄声无息地变成了multiset！太可怕了！
所以，为正确的容器挑选正确的比较函数，很重要。用好 STL 其实并不容易，用错了不仅执行效率狂低，而且还可能出现这些难以想象的意外……


Related posts:避免在 C++ 类结构中出现私有虚成员函数
do...while(0) 的妙用
让 C++ 的 new 操作失败时返回空指针



Related posts:<ul><li><a href='http://wutiam.net/2010/07/avoid-private-virtual-member-function-in-cpp-class/' rel='bookmark' title='Permanent Link: 避免在 C++ 类结构中出现私有虚成员函数'>避免在 C++ 类结构中出现私有虚成员函数</a></li>
<li><a href='http://wutiam.net/2010/03/ingenious-usage-of-do-while-0/' rel='bookmark' title='Permanent Link: do...while(0) 的妙用'>do...while(0) 的妙用</a></li>
<li><a href='http://wutiam.net/2010/02/let-cpp-new-operator-return-null-when-failed/' rel='bookmark' title='Permanent Link: 让 C++ 的 new 操作失败时返回空指针'>让 C++ 的 new 操作失败时返回空指针</a></li>
</ul>]]></description>
			<content:encoded><![CDATA[<p>根据《Effective STL》条款21中的例子，建立一个比较类型为 less_equal 的 set 容器：</p>

<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;">    set<span style="color: #000080;">&lt;</span> <span style="color: #0000ff;">int</span>, less_equal<span style="color: #000080;">&lt;</span><span style="color: #0000ff;">int</span><span style="color: #000080;">&gt;</span> <span style="color: #000080;">&gt;</span> s<span style="color: #008080;">;</span></pre></div></div>

<p>然后连续插入两个10：</p>

<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;">    s.<span style="color: #007788;">insert</span><span style="color: #008000;">&#40;</span><span style="color: #0000dd;">10</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> <span style="color: #666666;">// 10a</span>
    s.<span style="color: #007788;">insert</span><span style="color: #008000;">&#40;</span><span style="color: #0000dd;">10</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> <span style="color: #666666;">// 10b</span></pre></div></div>

<p>会得到什么？</p>
<p>在debug下，可能会给出一个assert报比较符号不合法，第二次插入失败，但在release下，这个动作很可能是未定义的，而通常的结果是，set中存在了两个键值同为10的项，也就是说，set被悄声无息地变成了multiset！太可怕了！</p>
<p>所以，为正确的容器挑选正确的比较函数，很重要。用好 STL 其实并不容易，用错了不仅执行效率狂低，而且还可能出现这些难以想象的意外……</p>


<p>Related posts:<ul><li><a href='http://wutiam.net/2010/07/avoid-private-virtual-member-function-in-cpp-class/' rel='bookmark' title='Permanent Link: 避免在 C++ 类结构中出现私有虚成员函数'>避免在 C++ 类结构中出现私有虚成员函数</a></li>
<li><a href='http://wutiam.net/2010/03/ingenious-usage-of-do-while-0/' rel='bookmark' title='Permanent Link: do...while(0) 的妙用'>do...while(0) 的妙用</a></li>
<li><a href='http://wutiam.net/2010/02/let-cpp-new-operator-return-null-when-failed/' rel='bookmark' title='Permanent Link: 让 C++ 的 new 操作失败时返回空指针'>让 C++ 的 new 操作失败时返回空指针</a></li>
</ul></p>]]></content:encoded>
			<wfw:commentRss>http://wutiam.net/2010/04/stl-on-the-wrong-way-may-lead-to-hell/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>do...while(0) 的妙用</title>
		<link>http://wutiam.net/2010/03/ingenious-usage-of-do-while-0/</link>
		<comments>http://wutiam.net/2010/03/ingenious-usage-of-do-while-0/#comments</comments>
		<pubDate>Tue, 02 Mar 2010 01:52:10 +0000</pubDate>
		<dc:creator>islet8</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[c++]]></category>

		<guid isPermaLink="false">http://wutiam.net/?p=127</guid>
		<description><![CDATA[在 C++ 中，有三种类型的循环语句：for、while 和 do...while，但是在一般应用中作循环时，我们可能用 for 和 while 要多一些，do...while 相对不受重视。
但是，最近在读我们项目的代码时，却发现了 do...while 的一些十分聪明的用法，不是用来做循环，而是用作其他来提高代码的健壮性。
转载自：http://www.cnblogs.com/flying_bat/archive/2008/01/18/1044693.html
1. do...while(0) 消除 goto 语句
通常，如果在一个函数中开始要分配一些资源，然后在中途执行过程中如果遇到错误则退出函数，当然，退出前先释放资源，我们的代码可能是这样：
[ Version 1 ]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
bool Execute&#40;&#41;
&#123;
   // 分配资源
   int *p = new int;
   bool bOk&#40;true&#41;;
&#160;
   // 执行并进行错误处理
   bOk = func1&#40;&#41;;
   if&#40;!bOk&#41; 
   &#123;
     [...]


Related posts:<ul><li><a href='http://wutiam.net/2009/08/logical-and-or-operation-in-ifdef/' rel='bookmark' title='Permanent Link: #ifdef 中的逻辑与或操作'>#ifdef 中的逻辑与或操作</a></li>
<li><a href='http://wutiam.net/2010/02/let-cpp-new-operator-return-null-when-failed/' rel='bookmark' title='Permanent Link: 让 C++ 的 new 操作失败时返回空指针'>让 C++ 的 new 操作失败时返回空指针</a></li>
<li><a href='http://wutiam.net/2010/07/avoid-private-virtual-member-function-in-cpp-class/' rel='bookmark' title='Permanent Link: 避免在 C++ 类结构中出现私有虚成员函数'>避免在 C++ 类结构中出现私有虚成员函数</a></li>
</ul>]]></description>
			<content:encoded><![CDATA[<p>在 C++ 中，有三种类型的循环语句：for、while 和 do...while，但是在一般应用中作循环时，我们可能用 for 和 while 要多一些，do...while 相对不受重视。<br />
但是，最近在读我们项目的代码时，却发现了 do...while 的一些十分聪明的用法，不是用来做循环，而是用作其他来提高代码的健壮性。</p>
<p><span id="more-127"></span>转载自：<a href="http://www.cnblogs.com/flying_bat/archive/2008/01/18/1044693.html">http://www.cnblogs.com/flying_bat/archive/2008/01/18/1044693.html</a></p>
<p><strong>1. do...while(0) 消除 goto 语句</strong></p>
<p>通常，如果在一个函数中开始要分配一些资源，然后在中途执行过程中如果遇到错误则退出函数，当然，退出前先释放资源，我们的代码可能是这样：</p>
<p>[ Version 1 ]</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
</pre></td><td class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">bool</span> Execute<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
   <span style="color: #666666;">// 分配资源</span>
   <span style="color: #0000ff;">int</span> <span style="color: #000040;">*</span>p <span style="color: #000080;">=</span> <span style="color: #0000dd;">new</span> <span style="color: #0000ff;">int</span><span style="color: #008080;">;</span>
   <span style="color: #0000ff;">bool</span> bOk<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">true</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
&nbsp;
   <span style="color: #666666;">// 执行并进行错误处理</span>
   bOk <span style="color: #000080;">=</span> func1<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
   <span style="color: #0000ff;">if</span><span style="color: #008000;">&#40;</span><span style="color: #000040;">!</span>bOk<span style="color: #008000;">&#41;</span> 
   <span style="color: #008000;">&#123;</span>
      <span style="color: #0000dd;">delete</span> p<span style="color: #008080;">;</span>   
      p <span style="color: #000080;">=</span> <span style="color: #0000ff;">NULL</span><span style="color: #008080;">;</span>
      <span style="color: #0000ff;">return</span> <span style="color: #0000ff;">false</span><span style="color: #008080;">;</span>
   <span style="color: #008000;">&#125;</span>
&nbsp;
   bOk <span style="color: #000080;">=</span> func2<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
   <span style="color: #0000ff;">if</span><span style="color: #008000;">&#40;</span><span style="color: #000040;">!</span>bOk<span style="color: #008000;">&#41;</span> 
   <span style="color: #008000;">&#123;</span>
      <span style="color: #0000dd;">delete</span> p<span style="color: #008080;">;</span>   
      p <span style="color: #000080;">=</span> <span style="color: #0000ff;">NULL</span><span style="color: #008080;">;</span>
      <span style="color: #0000ff;">return</span> <span style="color: #0000ff;">false</span><span style="color: #008080;">;</span>
   <span style="color: #008000;">&#125;</span>
&nbsp;
   bOk <span style="color: #000080;">=</span> func3<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
   <span style="color: #0000ff;">if</span><span style="color: #008000;">&#40;</span><span style="color: #000040;">!</span>bOk<span style="color: #008000;">&#41;</span> 
   <span style="color: #008000;">&#123;</span>
      <span style="color: #0000dd;">delete</span> p<span style="color: #008080;">;</span>   
      p <span style="color: #000080;">=</span> <span style="color: #0000ff;">NULL</span><span style="color: #008080;">;</span>
      <span style="color: #0000ff;">return</span> <span style="color: #0000ff;">false</span><span style="color: #008080;">;</span>
   <span style="color: #008000;">&#125;</span>
&nbsp;
   <span style="color: #666666;">// ..........</span>
&nbsp;
   <span style="color: #666666;">// 执行成功，释放资源并返回</span>
    <span style="color: #0000dd;">delete</span> p<span style="color: #008080;">;</span>   
    p <span style="color: #000080;">=</span> <span style="color: #0000ff;">NULL</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">return</span> <span style="color: #0000ff;">true</span><span style="color: #008080;">;</span>
&nbsp;
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>这里一个最大的问题就是代码的冗余，而且我每增加一个操作，就需要做相应的错误处理，非常不灵活。于是我们想到了 goto:</p>
<p>[ Version 2 ]</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
</pre></td><td class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">bool</span> Execute<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
   <span style="color: #666666;">// 分配资源</span>
   <span style="color: #0000ff;">int</span> <span style="color: #000040;">*</span>p <span style="color: #000080;">=</span> <span style="color: #0000dd;">new</span> <span style="color: #0000ff;">int</span><span style="color: #008080;">;</span>
   <span style="color: #0000ff;">bool</span> bOk<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">true</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
&nbsp;
   <span style="color: #666666;">// 执行并进行错误处理</span>
   bOk <span style="color: #000080;">=</span> func1<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
   <span style="color: #0000ff;">if</span><span style="color: #008000;">&#40;</span><span style="color: #000040;">!</span>bOk<span style="color: #008000;">&#41;</span> <span style="color: #0000ff;">goto</span> errorhandle<span style="color: #008080;">;</span>
&nbsp;
   bOk <span style="color: #000080;">=</span> func2<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
   <span style="color: #0000ff;">if</span><span style="color: #008000;">&#40;</span><span style="color: #000040;">!</span>bOk<span style="color: #008000;">&#41;</span> <span style="color: #0000ff;">goto</span> errorhandle<span style="color: #008080;">;</span>
&nbsp;
   bOk <span style="color: #000080;">=</span> func3<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
   <span style="color: #0000ff;">if</span><span style="color: #008000;">&#40;</span><span style="color: #000040;">!</span>bOk<span style="color: #008000;">&#41;</span> <span style="color: #0000ff;">goto</span> errorhandle<span style="color: #008080;">;</span>
&nbsp;
   <span style="color: #666666;">// ..........</span>
&nbsp;
   <span style="color: #666666;">// 执行成功，释放资源并返回</span>
    <span style="color: #0000dd;">delete</span> p<span style="color: #008080;">;</span>   
    p <span style="color: #000080;">=</span> <span style="color: #0000ff;">NULL</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">return</span> <span style="color: #0000ff;">true</span><span style="color: #008080;">;</span>
&nbsp;
errorhandle<span style="color: #008080;">:</span>
    <span style="color: #0000dd;">delete</span> p<span style="color: #008080;">;</span>   
    p <span style="color: #000080;">=</span> <span style="color: #0000ff;">NULL</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">return</span> <span style="color: #0000ff;">false</span><span style="color: #008080;">;</span>
&nbsp;
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>代码冗余是消除了，但是我们引入了 C++ 中身份比较微妙的 goto 语句，虽然正确的使用 goto 可以大大提高程序的灵活性与简洁性，但太灵活的东西往往是很危险的，它会让我们的程序捉摸不定，那么怎么才能避免使用 goto 语句，又能消除代码冗余呢，请看 do...while(0) 循环：</p>
<p>[ Version3 ]</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
</pre></td><td class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">bool</span> Execute<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
   <span style="color: #666666;">// 分配资源</span>
   <span style="color: #0000ff;">int</span> <span style="color: #000040;">*</span>p <span style="color: #000080;">=</span> <span style="color: #0000dd;">new</span> <span style="color: #0000ff;">int</span><span style="color: #008080;">;</span>
&nbsp;
   <span style="color: #0000ff;">bool</span> bOk<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">true</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
   <span style="color: #0000ff;">do</span>
   <span style="color: #008000;">&#123;</span>
      <span style="color: #666666;">// 执行并进行错误处理</span>
      bOk <span style="color: #000080;">=</span> func1<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
      <span style="color: #0000ff;">if</span><span style="color: #008000;">&#40;</span><span style="color: #000040;">!</span>bOk<span style="color: #008000;">&#41;</span> <span style="color: #0000ff;">break</span><span style="color: #008080;">;</span>
&nbsp;
      bOk <span style="color: #000080;">=</span> func2<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
      <span style="color: #0000ff;">if</span><span style="color: #008000;">&#40;</span><span style="color: #000040;">!</span>bOk<span style="color: #008000;">&#41;</span> <span style="color: #0000ff;">break</span><span style="color: #008080;">;</span>
&nbsp;
      bOk <span style="color: #000080;">=</span> func3<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
      <span style="color: #0000ff;">if</span><span style="color: #008000;">&#40;</span><span style="color: #000040;">!</span>bOk<span style="color: #008000;">&#41;</span> <span style="color: #0000ff;">break</span><span style="color: #008080;">;</span>
&nbsp;
      <span style="color: #666666;">// ..........</span>
&nbsp;
   <span style="color: #008000;">&#125;</span><span style="color: #0000ff;">while</span><span style="color: #008000;">&#40;</span><span style="color: #0000dd;">0</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
&nbsp;
    <span style="color: #666666;">// 释放资源</span>
    <span style="color: #0000dd;">delete</span> p<span style="color: #008080;">;</span>   
    p <span style="color: #000080;">=</span> <span style="color: #0000ff;">NULL</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">return</span> bOk<span style="color: #008080;">;</span>
&nbsp;
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>“漂亮！”， 看代码就行了，啥都不用说了...</p>
<p><strong>2. 宏定义中的 do...while(0)</strong></p>
<p>如果你是 C++ 程序员，我有理由相信你用过，或者接触过，至少听说过MFC, 在 MFC的afx.h 文件里面， 你会发现很多宏定义都是用了 do...while(0) 或 do...while(false)， 比如说：</p>

<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #339900;">#define AFXASSUME(cond) do { bool __afx_condVal=!!(cond); ASSERT(__afx_condVal); __analysis_assume(__afx_condVal); } while(0)</span></pre></div></div>

<p>粗看我们就会觉得很奇怪，既然循环里面只执行了一次，我要这个看似多余的 do...while(0) 有什么意义呢？<br />
当然有！<br />
为了看起来更清晰，这里用一个简单点的宏来演示：</p>

<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #339900;">#define SAFE_DELETE(p) do{ delete p; p = NULL} while(0)</span></pre></div></div>

<p>假设这里去掉 do...while(0),</p>

<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #339900;">#define SAFE_DELETE(p) delete p; p = NULL;</span></pre></div></div>

<p>那么以下代码：</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
</pre></td><td class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">if</span><span style="color: #008000;">&#40;</span><span style="color: #0000ff;">NULL</span> <span style="color: #000040;">!</span><span style="color: #000080;">=</span> p<span style="color: #008000;">&#41;</span> SAFE_DELETE<span style="color: #008000;">&#40;</span>p<span style="color: #008000;">&#41;</span>
<span style="color: #0000ff;">else</span>   ...<span style="color: #0000ff;">do</span> sth...</pre></td></tr></table></div>

<p>就有两个问题：<br />
1) 因为if分支后有两个语句，else分支没有对应的if，编译失败；<br />
2) 假设没有else, SAFE_DELETE中的第二个语句无论if测试是否通过，会永远执行。<br />
你可能发现，为了避免这两个问题，我不一定要用这个令人费解的do...while,  我直接用{}括起来就可以了：</p>

<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #339900;">#define SAFE_DELETE(p) { delete p; p = NULL;}</span></pre></div></div>

<p>的确，这样的话上面的问题是不存在了，但是我想对于C++程序员来讲，在每个语句后面加分号是一种约定俗成的习惯，这样的话，以下代码:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
</pre></td><td class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">if</span><span style="color: #008000;">&#40;</span><span style="color: #0000ff;">NULL</span> <span style="color: #000040;">!</span><span style="color: #000080;">=</span> p<span style="color: #008000;">&#41;</span> SAFE_DELETE<span style="color: #008000;">&#40;</span>p<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
<span style="color: #0000ff;">else</span>   ...<span style="color: #0000ff;">do</span> sth...</pre></td></tr></table></div>

<p>其 else 分支就无法通过编译了（原因同上），所以采用 do...while(0) 是做好的选择了。<br />
也许你会说，我们代码的习惯是在每个判断后面加上{}, 就不会有这种问题了，也就不需要 do...while 了，如：</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
</pre></td><td class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">if</span><span style="color: #008000;">&#40;</span>...<span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
<span style="color: #008000;">&#125;</span>
<span style="color: #0000ff;">else</span>
<span style="color: #008000;">&#123;</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>诚然，这是一个好的，应该提倡的编程习惯，但一般这样的宏都是作为 library 的一部分出现的，而对于一个 library 的作者，他所要做的就是让其库具有通用性，强壮性，因此他不能有任何对库的使用者的假设，如其编码规范，技术水平等。 </p>


<p>Related posts:<ul><li><a href='http://wutiam.net/2009/08/logical-and-or-operation-in-ifdef/' rel='bookmark' title='Permanent Link: #ifdef 中的逻辑与或操作'>#ifdef 中的逻辑与或操作</a></li>
<li><a href='http://wutiam.net/2010/02/let-cpp-new-operator-return-null-when-failed/' rel='bookmark' title='Permanent Link: 让 C++ 的 new 操作失败时返回空指针'>让 C++ 的 new 操作失败时返回空指针</a></li>
<li><a href='http://wutiam.net/2010/07/avoid-private-virtual-member-function-in-cpp-class/' rel='bookmark' title='Permanent Link: 避免在 C++ 类结构中出现私有虚成员函数'>避免在 C++ 类结构中出现私有虚成员函数</a></li>
</ul></p>]]></content:encoded>
			<wfw:commentRss>http://wutiam.net/2010/03/ingenious-usage-of-do-while-0/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>让 C++ 的 new 操作失败时返回空指针</title>
		<link>http://wutiam.net/2010/02/let-cpp-new-operator-return-null-when-failed/</link>
		<comments>http://wutiam.net/2010/02/let-cpp-new-operator-return-null-when-failed/#comments</comments>
		<pubDate>Thu, 25 Feb 2010 01:33:52 +0000</pubDate>
		<dc:creator>islet8</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[c++]]></category>

		<guid isPermaLink="false">http://wutiam.net/?p=124</guid>
		<description><![CDATA[C 中如果创建一个对象失败，就会返回空指针。但是对于 C++ 就不一样了，new 是不应返回空指针的，书上的推荐做法是在构造函数里抛异常。
当不想引入异常机制的时候，一般的做法是在构造器里啥都不做（最多做个变量初始化），加一个 Init() 函数来完成真正的初始化工作。
然而这样就使得每次创建一个对象，都要执行两步（new+init），总不是太方便，其实 C++ 的 new 操作符是带参的，可以通过“new(std::nothrow) CXxx”的方式让 new 失败时返回 null 指针，来标记失败（而不是抛出异常）。


Related posts:do...while(0) 的妙用
避免在 C++ 类结构中出现私有虚成员函数
乱用 STL 是地狱



Related posts:<ul><li><a href='http://wutiam.net/2010/03/ingenious-usage-of-do-while-0/' rel='bookmark' title='Permanent Link: do...while(0) 的妙用'>do...while(0) 的妙用</a></li>
<li><a href='http://wutiam.net/2010/07/avoid-private-virtual-member-function-in-cpp-class/' rel='bookmark' title='Permanent Link: 避免在 C++ 类结构中出现私有虚成员函数'>避免在 C++ 类结构中出现私有虚成员函数</a></li>
<li><a href='http://wutiam.net/2010/04/stl-on-the-wrong-way-may-lead-to-hell/' rel='bookmark' title='Permanent Link: 乱用 STL 是地狱'>乱用 STL 是地狱</a></li>
</ul>]]></description>
			<content:encoded><![CDATA[<p>C 中如果创建一个对象失败，就会返回空指针。但是对于 C++ 就不一样了，new 是不应返回空指针的，书上的推荐做法是在构造函数里抛异常。<br />
当不想引入异常机制的时候，一般的做法是在构造器里啥都不做（最多做个变量初始化），加一个 Init() 函数来完成真正的初始化工作。<br />
然而这样就使得每次创建一个对象，都要执行两步（new+init），总不是太方便，其实 C++ 的 new 操作符是带参的，可以通过“<strong>new(std::nothrow) CXxx</strong>”的方式让 new 失败时返回 null 指针，来标记失败（而不是抛出异常）。</p>


<p>Related posts:<ul><li><a href='http://wutiam.net/2010/03/ingenious-usage-of-do-while-0/' rel='bookmark' title='Permanent Link: do...while(0) 的妙用'>do...while(0) 的妙用</a></li>
<li><a href='http://wutiam.net/2010/07/avoid-private-virtual-member-function-in-cpp-class/' rel='bookmark' title='Permanent Link: 避免在 C++ 类结构中出现私有虚成员函数'>避免在 C++ 类结构中出现私有虚成员函数</a></li>
<li><a href='http://wutiam.net/2010/04/stl-on-the-wrong-way-may-lead-to-hell/' rel='bookmark' title='Permanent Link: 乱用 STL 是地狱'>乱用 STL 是地狱</a></li>
</ul></p>]]></content:encoded>
			<wfw:commentRss>http://wutiam.net/2010/02/let-cpp-new-operator-return-null-when-failed/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>严重避免在构造/析构过程中调用虚函数</title>
		<link>http://wutiam.net/2010/01/prevent-invoking-virtual-functions-in-constructor-and-destructor/</link>
		<comments>http://wutiam.net/2010/01/prevent-invoking-virtual-functions-in-constructor-and-destructor/#comments</comments>
		<pubDate>Fri, 29 Jan 2010 03:28:16 +0000</pubDate>
		<dc:creator>islet8</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[c++]]></category>

		<guid isPermaLink="false">http://wutiam.net/?p=123</guid>
		<description><![CDATA[之前只知道在 C++ 的构造器中，调用虚函数（非纯虚函数）不会出现多态的情况，却想当然认为既然析构器可以被声明为虚“函数”，那么析构器应该是能实现虚函数调用的的多态结果的。
事实证明，我又被蒙骗了！
构造器/析构器不会在调用虚函数时执行子类的重载实现，而且更危险的是当构造器/析构器“间接地”调用了虚函数（例如调用了一个非虚函数，但这个函数里调用了虚函数），不仅子类的重载实现不会被执行，而且还很难发现这种 bug。
所以，切记，切忌在构造器/析构器中直接或间接地调用任何虚函数！（单是在构造器/析构器中直接或间接地调用其他对象的虚函数并不受影响）


Related posts:避免在 C++ 类结构中出现私有虚成员函数
do...while(0) 的妙用
让 C++ 的 new 操作失败时返回空指针



Related posts:<ul><li><a href='http://wutiam.net/2010/07/avoid-private-virtual-member-function-in-cpp-class/' rel='bookmark' title='Permanent Link: 避免在 C++ 类结构中出现私有虚成员函数'>避免在 C++ 类结构中出现私有虚成员函数</a></li>
<li><a href='http://wutiam.net/2010/03/ingenious-usage-of-do-while-0/' rel='bookmark' title='Permanent Link: do...while(0) 的妙用'>do...while(0) 的妙用</a></li>
<li><a href='http://wutiam.net/2010/02/let-cpp-new-operator-return-null-when-failed/' rel='bookmark' title='Permanent Link: 让 C++ 的 new 操作失败时返回空指针'>让 C++ 的 new 操作失败时返回空指针</a></li>
</ul>]]></description>
			<content:encoded><![CDATA[<p>之前只知道在 C++ 的构造器中，调用虚函数（非纯虚函数）不会出现多态的情况，却想当然认为既然析构器可以被声明为虚“函数”，那么析构器应该是能实现虚函数调用的的多态结果的。<br />
事实证明，我又被蒙骗了！</p>
<p>构造器/析构器不会在调用虚函数时执行子类的重载实现，而且更危险的是当构造器/析构器“间接地”调用了虚函数（例如调用了一个非虚函数，但这个函数里调用了虚函数），不仅子类的重载实现不会被执行，而且还很难发现这种 bug。</p>
<p>所以，切记，<strong>切忌在构造器/析构器中直接或间接地调用任何虚函数！</strong>（单是在构造器/析构器中直接或间接地调用其他对象的虚函数并不受影响）</p>


<p>Related posts:<ul><li><a href='http://wutiam.net/2010/07/avoid-private-virtual-member-function-in-cpp-class/' rel='bookmark' title='Permanent Link: 避免在 C++ 类结构中出现私有虚成员函数'>避免在 C++ 类结构中出现私有虚成员函数</a></li>
<li><a href='http://wutiam.net/2010/03/ingenious-usage-of-do-while-0/' rel='bookmark' title='Permanent Link: do...while(0) 的妙用'>do...while(0) 的妙用</a></li>
<li><a href='http://wutiam.net/2010/02/let-cpp-new-operator-return-null-when-failed/' rel='bookmark' title='Permanent Link: 让 C++ 的 new 操作失败时返回空指针'>让 C++ 的 new 操作失败时返回空指针</a></li>
</ul></p>]]></content:encoded>
			<wfw:commentRss>http://wutiam.net/2010/01/prevent-invoking-virtual-functions-in-constructor-and-destructor/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>#ifdef 中的逻辑与或操作</title>
		<link>http://wutiam.net/2009/08/logical-and-or-operation-in-ifdef/</link>
		<comments>http://wutiam.net/2009/08/logical-and-or-operation-in-ifdef/#comments</comments>
		<pubDate>Thu, 20 Aug 2009 02:40:05 +0000</pubDate>
		<dc:creator>islet8</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[c++]]></category>

		<guid isPermaLink="false">http://wutiam.net/?p=109</guid>
		<description><![CDATA[原本用宏定义包起来的代码类似如下：

#ifndef A
// codes
#endif // A

现在要加入一个宏定义 B，实现类似这样的条件判断（显然实际上这样是不行的）：

#ifndef A &#38;&#38; ifdef B

其实应该这样：

#if (!defined A) &#38;&#38; (defined B)
// codes
#endif // !A &#38;&#38; B

这就修正了之前一直以为的“既生 #ifdef，何生 #if defined”的思维，其实还是有差别的。


Related posts:避免在 C++ 类结构中出现私有虚成员函数
乱用 STL 是地狱
do...while(0) 的妙用



Related posts:<ul><li><a href='http://wutiam.net/2010/07/avoid-private-virtual-member-function-in-cpp-class/' rel='bookmark' title='Permanent Link: 避免在 C++ 类结构中出现私有虚成员函数'>避免在 C++ 类结构中出现私有虚成员函数</a></li>
<li><a href='http://wutiam.net/2010/04/stl-on-the-wrong-way-may-lead-to-hell/' rel='bookmark' title='Permanent Link: 乱用 STL 是地狱'>乱用 STL 是地狱</a></li>
<li><a href='http://wutiam.net/2010/03/ingenious-usage-of-do-while-0/' rel='bookmark' title='Permanent Link: do...while(0) 的妙用'>do...while(0) 的妙用</a></li>
</ul>]]></description>
			<content:encoded><![CDATA[<p>原本用宏定义包起来的代码类似如下：</p>

<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #339900;">#ifndef A</span>
<span style="color: #666666;">// codes</span>
<span style="color: #339900;">#endif // A</span></pre></div></div>

<p>现在要加入一个宏定义 B，实现类似这样的条件判断（显然实际上这样是不行的）：</p>

<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #339900;">#ifndef A &amp;&amp; ifdef B</span></pre></div></div>

<p>其实应该这样：</p>

<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #339900;">#if (!defined A) &amp;&amp; (defined B)</span>
<span style="color: #666666;">// codes</span>
<span style="color: #339900;">#endif // !A &amp;&amp; B</span></pre></div></div>

<p>这就修正了之前一直以为的“既生 #ifdef，何生 #if defined”的思维，其实还是<a title="#if define (abc)与#ifdef abc 有什么区别?" href="http://zhidao.baidu.com/question/40577172.html">有差别的</a>。</p>


<p>Related posts:<ul><li><a href='http://wutiam.net/2010/07/avoid-private-virtual-member-function-in-cpp-class/' rel='bookmark' title='Permanent Link: 避免在 C++ 类结构中出现私有虚成员函数'>避免在 C++ 类结构中出现私有虚成员函数</a></li>
<li><a href='http://wutiam.net/2010/04/stl-on-the-wrong-way-may-lead-to-hell/' rel='bookmark' title='Permanent Link: 乱用 STL 是地狱'>乱用 STL 是地狱</a></li>
<li><a href='http://wutiam.net/2010/03/ingenious-usage-of-do-while-0/' rel='bookmark' title='Permanent Link: do...while(0) 的妙用'>do...while(0) 的妙用</a></li>
</ul></p>]]></content:encoded>
			<wfw:commentRss>http://wutiam.net/2009/08/logical-and-or-operation-in-ifdef/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>用 前置声明，还是用 #include？</title>
		<link>http://wutiam.net/2009/05/forward-declaration-or-include/</link>
		<comments>http://wutiam.net/2009/05/forward-declaration-or-include/#comments</comments>
		<pubDate>Mon, 25 May 2009 11:30:21 +0000</pubDate>
		<dc:creator>islet8</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[c++]]></category>

		<guid isPermaLink="false">http://wutiam.net/?p=99</guid>
		<description><![CDATA[为了能让编译速度快一点，明智之举是使用前置声明，而不是 #include 整个头文件。
那声明时候可以用前置声明，而什么时候必须 #include 头文件呢？简单的说：

当不需要用到类型的具体实现时，包括构造器、赋值运算符、成员函数等，只需要前置声明就可以了
当需要用到类型的以上方法时，就不得不 #include 整个头文件


对该技巧的具体分析可以参考这里和这里。


Related posts:避免在 C++ 类结构中出现私有虚成员函数
乱用 STL 是地狱
do...while(0) 的妙用



Related posts:<ul><li><a href='http://wutiam.net/2010/07/avoid-private-virtual-member-function-in-cpp-class/' rel='bookmark' title='Permanent Link: 避免在 C++ 类结构中出现私有虚成员函数'>避免在 C++ 类结构中出现私有虚成员函数</a></li>
<li><a href='http://wutiam.net/2010/04/stl-on-the-wrong-way-may-lead-to-hell/' rel='bookmark' title='Permanent Link: 乱用 STL 是地狱'>乱用 STL 是地狱</a></li>
<li><a href='http://wutiam.net/2010/03/ingenious-usage-of-do-while-0/' rel='bookmark' title='Permanent Link: do...while(0) 的妙用'>do...while(0) 的妙用</a></li>
</ul>]]></description>
			<content:encoded><![CDATA[<p>为了能让编译速度快一点，明智之举是使用<strong>前置声明</strong>，而不是 #include 整个头文件。</p>
<p>那声明时候可以用前置声明，而什么时候必须 #include 头文件呢？简单的说：</p>
<ol>
<li>当不需要用到类型的具体实现时，包括<strong>构造器</strong><span>、<strong>赋值运算符</strong>、<strong>成员函数</strong>等，只需要前置声明就可以了</span></li>
<li>当需要用到类型的以上方法时，就不得不 <span>#include 整个头文件<br />
</span></li>
</ol>
<p>对该技巧的具体分析可以参考<a title="正确使用#include和前置声明(forward declaration)" href="http://blog.csdn.net/SpriteLW/archive/2006/07/23/965702.aspx">这里</a>和<a title="如何使用前置声明取代包括头文件" href="http://blog.csdn.net/rogeryi/archive/2006/12/12/1439597.aspx">这里</a>。</p>


<p>Related posts:<ul><li><a href='http://wutiam.net/2010/07/avoid-private-virtual-member-function-in-cpp-class/' rel='bookmark' title='Permanent Link: 避免在 C++ 类结构中出现私有虚成员函数'>避免在 C++ 类结构中出现私有虚成员函数</a></li>
<li><a href='http://wutiam.net/2010/04/stl-on-the-wrong-way-may-lead-to-hell/' rel='bookmark' title='Permanent Link: 乱用 STL 是地狱'>乱用 STL 是地狱</a></li>
<li><a href='http://wutiam.net/2010/03/ingenious-usage-of-do-while-0/' rel='bookmark' title='Permanent Link: do...while(0) 的妙用'>do...while(0) 的妙用</a></li>
</ul></p>]]></content:encoded>
			<wfw:commentRss>http://wutiam.net/2009/05/forward-declaration-or-include/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
