﻿<?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++博客-(define (cuigang) (coding))-文章分类-《C++设计新思维》读书笔记</title><link>http://www.cppblog.com/cuigang/category/5814.html</link><description>(define (coding) (coding))
</description><language>zh-cn</language><lastBuildDate>Wed, 21 May 2008 14:34:12 GMT</lastBuildDate><pubDate>Wed, 21 May 2008 14:34:12 GMT</pubDate><ttl>60</ttl><item><title>《C++设计新思维》读书笔记（23）</title><link>http://www.cppblog.com/cuigang/articles/41045.html</link><dc:creator>cuigang</dc:creator><author>cuigang</author><pubDate>Sat, 12 Jan 2008 12:29:00 GMT</pubDate><guid>http://www.cppblog.com/cuigang/articles/41045.html</guid><wfw:comment>http://www.cppblog.com/cuigang/comments/41045.html</wfw:comment><comments>http://www.cppblog.com/cuigang/articles/41045.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/cuigang/comments/commentRss/41045.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cuigang/services/trackbacks/41045.html</trackback:ping><description><![CDATA[<div class="Section1" style="font-family: courier new;">
<p><font size="2">4.4
Chunks</font><font size="2">（大块内存）</font></p>
<p><font size="2">每个</font><font size="2">Chunk</font><font size="2">对象包含并管理一大块内存，其中包含固定数量的区块。你可以在构造期间设定区块的大小和数量。你可以从</font><font size="2">chunk</font><font size="2">中分配和归还区块。一旦</font><font size="2">chunk</font><font size="2">之中没有剩余区块，分配函数便传回</font><font size="2">0</font><font size="2">。</font><font size="2">chunk</font><font size="2">定义如下：</font></p>
<p><font color="green" size="2">
<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>--><font>//</font><font>&nbsp;Nothing&nbsp;is&nbsp;private&nbsp;-&nbsp;Chunk&nbsp;is&nbsp;a&nbsp;Plain&nbsp;Old&nbsp;Data&nbsp;(POD)&nbsp;structure<br></font><font>//</font><font>&nbsp;structure&nbsp;defined&nbsp;inside&nbsp;FixedAllocator<br></font><font>//</font><font>&nbsp;and&nbsp;manipulated&nbsp;only&nbsp;by&nbsp;it</font><font><br></font><font>struct</font><font>&nbsp;Chunk{<br>&nbsp;&nbsp;&nbsp;&nbsp;</font><font>void</font><font>&nbsp;Init(std::size_t&nbsp;blockSize,&nbsp;unsigned&nbsp;</font><font>char</font><font>&nbsp;blocks);<br>&nbsp;&nbsp;&nbsp;&nbsp;</font><font>void</font><font>&nbsp;Release();<br>&nbsp;&nbsp;&nbsp;&nbsp;</font><font>void</font><font>*</font><font>&nbsp;Allocate(std::size_t&nbsp;blockSize);<br>&nbsp;&nbsp;&nbsp;&nbsp;</font><font>void</font><font>&nbsp;Deallocate(</font><font>void</font><font>*</font><font>&nbsp;p,&nbsp;std::size_t&nbsp;blockSize);<br>&nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;</font><font>char</font><font>*</font><font>&nbsp;pData_;<br>&nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;</font><font>char</font><font><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;firstAvailableBlock_,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;blocksAvailable_;<br>};</font></div>
<br>
</font></p>
<p><font size="2">除了一个指针指向被管理内存本身，</font><font size="2">firstAvailableBlock_</font><font size="2">保存</font><font size="2">chunk</font><font size="2">内第一个可用区块的索引，</font><font size="2">blocksAvailable_</font><font size="2">保存</font><font size="2">chunk</font><font size="2">内可用区块总数。</font></p>
<p><font size="2">Chunk</font><font size="2">的接口非常简单。</font><font size="2">Init()</font><font size="2">用于初始化，</font><font size="2">Release()</font><font size="2">用来释放。</font><font size="2">Allocate()</font><font size="2">用来分配，</font><font size="2">Deallocate()</font><font size="2">用来归还。</font><font size="2">Chunk</font><font size="2">不保存区块的大小，它没有构造函数、析构函数和赋值运算符，定义自己的</font><font size="2">copy</font><font size="2">语义会损及上一层的效率</font><font size="2">——</font><font size="2">上一层将</font><font size="2">chunk</font><font size="2">置于一个</font><font size="2">vector</font><font size="2">。</font></p>
<p><font size="2">chunk</font><font size="2">的结构反应出设计中一个重要折衷。</font><font size="2">blocksAvailable_</font><font size="2">和</font><font size="2">firstAvailableBlock_</font><font size="2">都是</font><font size="2">unsigned char</font><font size="2">型别，因此一个</font><font size="2">chunk</font><font size="2">无法拥有</font><font size="2">255</font><font size="2">个以上的区块。</font></p>
<p><font size="2">另外我们利用</font><font size="2">&#8220;</font><font size="2">未被使用的区块</font><font size="2">&#8221;</font><font size="2">的第一个</font><font size="2">bytes</font><font size="2">来存放下一个</font><font size="2">&#8220;</font><font size="2">未被使用的区块</font><font size="2">&#8221;</font><font size="2">的索引号。这样我们就拥有了一个单向链表。无需占用内存。</font></p>
<p><font size="2">初始化函数如下：</font></p>
<p><font color="green" size="2">
<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>--><font>void</font><font>&nbsp;Chunk::Init(std::size_t&nbsp;blockSize,&nbsp;unsigned&nbsp;</font><font>char</font><font>&nbsp;blocks){<br>&nbsp;&nbsp;&nbsp;&nbsp;pData_&nbsp;</font><font>=</font><font>&nbsp;</font><font>new</font><font>&nbsp;unsigned&nbsp;</font><font>char</font><font>[blockSize&nbsp;</font><font>*</font><font>&nbsp;blocks];<br>&nbsp;&nbsp;&nbsp;&nbsp;firstAvailableBlock_&nbsp;</font><font>=</font><font>&nbsp;</font><font>0</font><font>;<br>&nbsp;&nbsp;&nbsp;&nbsp;blocksAvailable_&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font>=</font><font>&nbsp;blcoks;<br>&nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;</font><font>char</font><font>&nbsp;i&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font>=</font><font>&nbsp;</font><font>0</font><font>;<br>&nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;</font><font>char</font><font>*</font><font>&nbsp;p&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font>=</font><font>&nbsp;pData_;<br>&nbsp;&nbsp;&nbsp;&nbsp;</font><font>for</font><font>(;&nbsp;i&nbsp;</font><font>!=</font><font>&nbsp;blocks;&nbsp;p&nbsp;</font><font>+=</font><font>&nbsp;blockSize){<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font>*</font><font>p&nbsp;</font><font>=</font><font>&nbsp;</font><font>++</font><font>i;<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br>}</font></div>
<br>
</font></p>
<p><font size="2">我们来看一下将区块数量限制在</font><font size="2">unsigned char</font><font size="2">的大小（</font><font size="2">0~255</font><font size="2">）的原因。假如我们使用一个较大型别，比如</font><font size="2">unsigned short</font><font size="2">（</font><font size="2">0~65535</font><font size="2">），我们将遭遇两个问题，一个小问题，一个大问题。</font></p>
<p><font size="2">小问题是我们无法分配小于</font><font size="2">sizeof(unsigned
short)</font><font size="2">的区块，这令人尴尬，因为我们正在建立一个小型对象分配器。（这里指的是，对于</font><font size="2">1 byte</font><font size="2">区块大小的</font><font size="2">chunk</font><font size="2">，由于索引号有</font><font size="2">2 bytes</font><font size="2">，无法建立内嵌的单向链表，</font><font size="2">cuigang</font><font size="2">）。</font></p>
<p><font size="2">大问题是齐位（</font><font size="2">alignment</font><font size="2">）问题。假设你为一个</font><font size="2">5 bytes</font><font size="2">区块建立一个专属分配器。这种情况下如果想将</font><font size="2">&#8220;</font><font size="2">指向如此一个</font><font size="2">5 bytes</font><font size="2">区块</font><font size="2">&#8221;</font><font size="2">的指针转换为</font><font size="2">unsigned int</font><font size="2">（原文如此，估计作者是想说从一个起始为奇地址的区块提领（</font><font size="2">dereference</font><font size="2">）一个偶字节变量会导致异常的问题，这几个函数中都有提领的动作。</font><font size="2">cuigang</font><font size="2">），会造成不确定行为。</font></p>
<p><font size="2">unsigned
char</font><font size="2">类型可以简单的解决这个问题。它大小为</font><font size="2">1</font><font size="2">，无齐位问题。只不过我们将无法分配多于</font><font size="2">255</font><font size="2">的区块。但这个我们是可以接受的。</font></p>
<p><font size="2">分配函数</font><font size="2">Allocate()</font><font size="2">是典型的</font><font size="2">list</font><font size="2">操作。</font></p>
<p><font color="green" size="2">
<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>--><font>void</font><font>*</font><font>&nbsp;Chunk::Allocate(std::size_t&nbsp;blockSize){<br>&nbsp;&nbsp;&nbsp;&nbsp;</font><font>if</font><font>(</font><font>!</font><font>blocksAvailable_)&nbsp;</font><font>return</font><font>&nbsp;</font><font>0</font><font>;<br>&nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;</font><font>char</font><font>*</font><font>&nbsp;pResult&nbsp;</font><font>=</font><font><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pData_&nbsp;</font><font>+</font><font>&nbsp;(firstAvailableBlock_&nbsp;</font><font>*</font><font>&nbsp;blockSize);<br>&nbsp;&nbsp;&nbsp;&nbsp;firstAvailableBlock_&nbsp;</font><font>=</font><font>&nbsp;</font><font>*</font><font>pResult;<br>&nbsp;&nbsp;&nbsp;&nbsp;</font><font>--</font><font>blocksAvailable_;<br>&nbsp;&nbsp;&nbsp;&nbsp;</font><font>return</font><font>&nbsp;pResult;<br>};</font></div>
<br>
</font></p>
<p><font size="2">这个函数成本很小，不需要查找动作，在常数事件内完成，而不像系统分配需要线性时间。</font></p>
<p><font size="2">归还函数</font><font size="2">Deallocate()</font><font size="2">行为相反，这里要注意，由于</font><font size="2">Chunk</font><font size="2">对区块大小一无所知，所以你必须将区块大小当作参数传入，同时注意里面很多的异常处理来避免你将错误指针传入：</font></p>
<p><font color="green" size="2">
<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>--><font>void</font><font>&nbsp;Chunk::Deallocate(</font><font>void</font><font>*</font><font>&nbsp;p,&nbsp;std::size_t&nbsp;blockSize){<br>&nbsp;&nbsp;&nbsp;&nbsp;assert(p&nbsp;</font><font>&gt;=</font><font>&nbsp;pData_);<br>&nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;</font><font>char</font><font>*</font><font>&nbsp;toRelease&nbsp;</font><font>=</font><font>&nbsp;static_cast</font><font>&lt;</font><font>unsigned&nbsp;</font><font>char</font><font>*&gt;</font><font>(p);<br>&nbsp;&nbsp;&nbsp;&nbsp;assert((toRelease&nbsp;</font><font>-</font><font>&nbsp;pData_)&nbsp;</font><font>%</font><font>&nbsp;blockSize&nbsp;</font><font>==</font><font>&nbsp;</font><font>0</font><font>);<br>&nbsp;&nbsp;&nbsp;&nbsp;</font><font>*</font><font>toRelease&nbsp;</font><font>=</font><font>&nbsp;firstAvailableBlock_;<br>&nbsp;&nbsp;&nbsp;&nbsp;firstAvailableBlcok_&nbsp;</font><font>=</font><font>&nbsp;static_cast</font><font>&lt;</font><font>unsigned&nbsp;</font><font>char</font><font>&gt;</font><font>(<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(toRelease&nbsp;</font><font>-</font><font>&nbsp;pData_)&nbsp;</font><font>/</font><font>&nbsp;blockSize);<br>&nbsp;&nbsp;&nbsp;&nbsp;assert(firstAvailableBlock&nbsp;</font><font>==</font><font>&nbsp;(toRelease&nbsp;</font><font>-</font><font>&nbsp;pData_)&nbsp;</font><font>/</font><font>&nbsp;blockSize);<br>&nbsp;&nbsp;&nbsp;&nbsp;</font><font>++</font><font>blocksAvailable_;<br>};</font></div>
<br>
</font></p>
</div>
<br><img src ="http://www.cppblog.com/cuigang/aggbug/41045.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cuigang/" target="_blank">cuigang</a> 2008-01-12 20:29 <a href="http://www.cppblog.com/cuigang/articles/41045.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>《C++设计新思维》读书笔记（22）</title><link>http://www.cppblog.com/cuigang/articles/40933.html</link><dc:creator>cuigang</dc:creator><author>cuigang</author><pubDate>Thu, 10 Jan 2008 15:00:00 GMT</pubDate><guid>http://www.cppblog.com/cuigang/articles/40933.html</guid><wfw:comment>http://www.cppblog.com/cuigang/comments/40933.html</wfw:comment><comments>http://www.cppblog.com/cuigang/articles/40933.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/cuigang/comments/commentRss/40933.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cuigang/services/trackbacks/40933.html</trackback:ping><description><![CDATA[<p><font face="Courier new" size="2">4.2
</font><font face="宋体" size="2">内存分配器的工作方式</font><font face="宋体" size="2"></font></p>
<p><font face="宋体" size="2">（本节内容可以参考操作系统书籍，</font><font face="Courier new" size="2">cuigang</font><font face="宋体" size="2">）</font><font face="宋体" size="2"></font></p>
<p><font face="宋体" size="2">内存分配器如何工作？它管理一个由</font><font face="Courier new" size="2">raw bytes</font><font face="宋体" size="2">所组成的内存池。薄记结构可以简单如下：</font><font face="宋体" size="2"></font></p>
<p><font color="green" face="Courier new" size="2">
<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;"><font>struct</font></span><span style="color: #000000;"><font>&nbsp;MemControlBlock{<br>&nbsp;&nbsp;&nbsp;&nbsp;std::size_t&nbsp;&nbsp;size_;<br>&nbsp;&nbsp;&nbsp;&nbsp;</font></span><span style="color: #0000ff;"><font>bool</font></span><span style="color: #000000;"><font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;available_;<br>};</font></span></div>
<br></font></p>
<p><font face="Courier new" size="2">MemControlBlock</font><font face="宋体" size="2">对象管理的内存紧随其后，大小</font><font face="Courier new" size="2"> size_</font><font face="宋体" size="2">，然后是另一个控制块。初始时，内存池中只有一个</font><font face="Courier new" size="2">MemControlBlock</font><font face="宋体" size="2">，并将所有内存视为一大块，这就是所谓</font><font face="Courier new" size="2">root</font><font face="宋体" size="2">控制块，永不离开最初位置。以</font>
</p>
<p><font color="green" face="Courier new" size="2">+===================+=================+==================+<br>
| available_ : ture | size_ : 1048571 |&nbsp;&nbsp; mem[1048571]&nbsp;&nbsp; |<br>
+===================+=================+==================+<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;&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;
|<br>
|-----&gt; 1 byte &lt;----|----&gt; 4 bytes &lt;--|-&gt; 1048571bytes &lt;-|<br>
|-----------------------&gt; 1048576 bytes &lt;----------------|</font><font face="宋体" size="2"></font></p>
<p><font face="宋体" size="2">每次分配都引发一次线性查找，找到一个合适区块，适合策略有最先匹配法则（</font><font face="Courier new" size="2">first fit</font><font face="宋体" size="2">）、最佳匹配（</font><font face="Courier new" size="2">best
fit</font><font face="宋体" size="2">），最差匹配（</font><font face="Courier new" size="2">worst fit</font><font face="宋体" size="2">），甚至随机匹配（</font><font face="Courier new" size="2">random fit</font><font face="宋体" size="2">）。有趣的是最差匹配比最佳匹配好！</font><font face="宋体" size="2"></font></p>
<p><font face="宋体" size="2">每次归还区块，同样需要一次线性搜索，找出待归还区块的前一区块并调整大小。</font><font face="宋体" size="2"></font></p>
<p><font face="宋体" size="2">如你所看，这一策略时间上并非高效。但空间上开销较小，甚至我们可以再调整：</font><font face="宋体" size="2"></font></p>
<p>
<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: #008000;">//</span><span style="color: #008000;">注意下面代码依赖编译器和平台</span><span style="color: #008000;"><br></span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;MemControlBlock{<br>&nbsp;&nbsp;&nbsp;&nbsp;std::size_t&nbsp;&nbsp;size_&nbsp;:&nbsp;</span><span style="color: #000000;">31</span><span style="color: #000000;">;<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;available_&nbsp;:&nbsp;</span><span style="color: #000000;">1</span><span style="color: #000000;">;<br>};</span></div>
<br><font color="green" face="Courier new" size="2"></font></p>
<p><font face="宋体" size="2">为了前序遍历，我们可以定义为双向链表：</font><font face="宋体" size="2"></font></p>
<p><font color="green" face="Courier new" size="2">
<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;"><font>struct</font></span><span style="color: #000000;"><font>&nbsp;MemControlBlock{<br>&nbsp;&nbsp;&nbsp;&nbsp;</font></span><span style="color: #0000ff;"><font>bool</font></span><span style="color: #000000;"><font>&nbsp;available_;<br>&nbsp;&nbsp;&nbsp;&nbsp;MemControlBlock</font></span><span style="color: #000000;"><font>*</font></span><span style="color: #000000;"><font>&nbsp;next_;<br>&nbsp;&nbsp;&nbsp;&nbsp;MemControlBlock</font></span><span style="color: #000000;"><font>*</font></span><span style="color: #000000;"><font>&nbsp;prev_;<br>};</font></span></div>
<br></font></p>
<p><font face="宋体" size="2">这里我们不需要</font><font face="Courier new" size="2">size_</font><font face="宋体" size="2">了，我们可以通过</font><font face="Courier new" size="2">this-&gt;next - this </font><font face="宋体" size="2">来得到。</font><font face="宋体" size="2"></font></p>
<p><font face="宋体" size="2">尽管如此，分配动作还是得消耗线性时间。要减轻这样的消耗，有如多巧妙技术可用，但都各有利弊，存在某种情况下的不良性能（参考</font><font face="Courier new" size="2">Knuth</font><font face="宋体" size="2">著作）。这里我们不对其讨论，我们的焦点是可最佳处理小型对象的</font><font face="Courier new" size="2">&#8220;</font><font face="宋体" size="2">专用分配器</font><font face="Courier new" size="2">&#8221;</font><font face="宋体" size="2">。</font><font face="宋体" size="2"></font></p>
<p><font face="Courier new" size="2">4.3
</font><font face="宋体" size="2">小型对象分配器</font><font face="宋体" size="2"></font></p>
<p><font face="宋体" size="2">本章介绍的小型对象分配器分为</font><font face="Courier new" size="2">4</font><font face="宋体" size="2">层结构。如图所示，下层提供功能供上层使用。</font><font face="宋体" size="2"></font></p>
<p><font color="green" face="Courier new" size="2">+-------------------+<br>
|&nbsp;&nbsp;&nbsp; SmallObject&nbsp;&nbsp;&nbsp; |<br>
+-------------------+<br>
| SmallObjAllocator |<br>
+-------------------+<br>
|&nbsp;&nbsp; FixedAllocator&nbsp; |<br>
+-------------------+<br>
|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Chunk&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
|<br>
+-------------------+</font><font face="宋体" size="2"></font></p>
<p><font face="宋体" size="2">最下层是</font><font face="Courier new" size="2">Chunk</font><font face="宋体" size="2">对象，每一个</font><font face="Courier new" size="2">Chunk</font><font face="宋体" size="2">管理一大块内存，此大块内存包含整数个固定大小的区块。可以用来分配和归还，当其中没有剩余时，分配失败返回零。</font><font face="宋体" size="2"></font></p>
<p><font face="宋体" size="2">第二层是</font><font face="Courier new" size="2">FixAllocator
class</font><font face="宋体" size="2">，其以</font><font face="Courier new" size="2">Chunk</font><font face="宋体" size="2">为构件。主要用来满足那些</font><font face="Courier new" size="2">&#8220;</font><font face="宋体" size="2">累计总量超过</font><font face="Courier new" size="2">Chunk</font><font face="宋体" size="2">容量</font><font face="Courier new" size="2">&#8221;</font><font face="宋体" size="2">的请求。</font><font face="Courier new" size="2">FixAllocator</font><font face="宋体" size="2">通过一个</font><font face="Courier new" size="2">array</font><font face="宋体" size="2">（实际是</font><font face="Courier new" size="2">vector</font><font face="宋体" size="2">）组合</font><font face="Courier new" size="2">Chunks</font><font face="宋体" size="2">。如果所有</font><font face="Courier new" size="2">Chunk</font><font face="宋体" size="2">都被使用，</font><font face="Courier new" size="2">FixAllocator</font><font face="宋体" size="2">分配新</font><font face="Courier new" size="2">Chunk</font><font face="宋体" size="2">，并加入</font><font face="Courier new" size="2">array</font><font face="宋体" size="2">，来满足需求。</font><font face="宋体" size="2"></font></p>
<p><font face="宋体" size="2">第三层是</font><font face="Courier new" size="2">SmallObjectAllocator</font><font face="宋体" size="2">提供通用分配</font><font face="Courier new" size="2">/</font><font face="宋体" size="2">归还函数。拥有数个</font><font face="Courier new" size="2">FixedAllocator</font><font face="宋体" size="2">对象，每个负责分配某特定大小对象。根据申请</font><font face="Courier new" size="2">bytes</font><font face="宋体" size="2">个数不同，</font><font face="Courier new" size="2">SmallObjAllocator</font><font face="宋体" size="2">对象会将内存分配申请分发。如果请求量过大，会转交系统</font><font face="Courier new" size="2">new</font><font face="宋体" size="2">。</font><font face="宋体" size="2"></font></p>
<font face="宋体" size="2">第四层是</font><font face="Courier new" size="2">SmallObject</font><font face="宋体" size="2">，它包装</font><font face="Courier new" size="2">FixedAllocator</font><font face="宋体" size="2">，以便向</font><font face="Courier new" size="2">C++
classes</font><font face="宋体" size="2">提供封装良好的分配服务。</font><font face="Courier new" size="2">SmallObject</font><font face="宋体" size="2">重载</font><font face="Courier new" size="2">new</font><font face="宋体" size="2">和</font><font face="Courier new" size="2">delete</font><font face="宋体" size="2">。你只需要让你的对象派生于</font><font face="Courier new" size="2">SmallObject</font><font face="宋体" size="2">。</font>
<br><img src ="http://www.cppblog.com/cuigang/aggbug/40933.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cuigang/" target="_blank">cuigang</a> 2008-01-10 23:00 <a href="http://www.cppblog.com/cuigang/articles/40933.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>《C++设计新思维》读书笔记（21）</title><link>http://www.cppblog.com/cuigang/articles/40932.html</link><dc:creator>cuigang</dc:creator><author>cuigang</author><pubDate>Thu, 10 Jan 2008 14:54:00 GMT</pubDate><guid>http://www.cppblog.com/cuigang/articles/40932.html</guid><wfw:comment>http://www.cppblog.com/cuigang/comments/40932.html</wfw:comment><comments>http://www.cppblog.com/cuigang/articles/40932.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/cuigang/comments/commentRss/40932.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cuigang/services/trackbacks/40932.html</trackback:ping><description><![CDATA[<p><font face="Courier new" size="2"></font></p>
<span style="font-size: 10pt;">
<p><font face="Courier new" size="2">3.13
</font><font face="宋体" size="2">运用</font><font face="Courier new" size="2">typelist</font><font face="宋体" size="2">自动产生</font><font face="Courier new" size="2">classes</font><font face="宋体" size="2">（不好意思，没太看懂，略去）</font><font face="宋体" size="2"></font></p>
<p><font face="Courier new" size="2">4
</font><font face="宋体" size="2">小型对象分配技术</font><font face="宋体" size="2"></font></p>
<p><font face="Courier new" size="2">4.1
</font><font face="宋体" size="2">缺省的</font><font face="Courier new" size="2">Free Store</font><font face="宋体" size="2">分配器</font><font face="宋体" size="2"></font></p>
<p><font face="宋体" size="2">由于某些</font><font face="Courier new" size="2">&#8220;</font><font face="宋体" size="2">神秘原因</font><font face="Courier new" size="2">&#8221;</font><font face="宋体" size="2">，系统缺省的</font><font face="Courier new" size="2">free store</font><font face="宋体" size="2">分配器速度极慢，恶名昭彰。其中一个可能的原因是，它通常只是</font><font face="Courier new" size="2">C heap</font><font face="宋体" size="2">分配器（</font><font face="Courier new" size="2">malloc/realloc/free</font><font face="宋体" size="2">）的浅层包装。</font><font face="Courier new" size="2">C heap</font><font face="宋体" size="2">分配器并未特别针对小块内存的分配进行优化。</font><font face="Courier new" size="2">C</font><font face="宋体" size="2">程序通常十分有条理地、保守地使用内存，却不会采用任何</font><font face="Courier new" size="2">&#8220;</font><font face="宋体" size="2">导致小块内存被大量分配</font><font face="Courier new" size="2">&#8221;</font><font face="宋体" size="2">的手法或技巧。</font><font face="Courier new" size="2">C</font><font face="宋体" size="2">程序通常分配中大型对象（数百或者数千个</font><font face="Courier new" size="2">bytes</font><font face="宋体" size="2">）。</font><font face="宋体" size="2"></font></p>
<p><font face="宋体" size="2">除了速度慢，</font><font face="Courier new" size="2">C++</font><font face="宋体" size="2">缺省分配器的通用性也造成小型对象空间分配的低效。（细述，指对小对象会额外分配空间，以保证不小于最小区块，而且链表的薄记管理部分也开销很大，对小对象比较多时尤为明显）。</font><font face="宋体" size="2"></font></p>
<p><font face="宋体" size="2">在</font><font face="Courier new" size="2">C++</font><font face="宋体" size="2">中，动态分配很重要。执行期多态性和动态分配的联系最为密切。</font><font face="Courier new" size="2">&#8220;Pimpl</font><font face="宋体" size="2">手法</font><font face="Courier new" size="2">&#8221;</font><font face="宋体" size="2">就要求</font><font face="Courier new" size="2">&#8220;</font><font face="宋体" size="2">以</font><font face="Courier new" size="2">free store</font><font face="宋体" size="2">分配取代</font><font face="Courier new" size="2">stack</font><font face="宋体" size="2">分配</font><font face="Courier new" size="2">&#8221;</font><font face="宋体" size="2">为前提。</font><font face="宋体" size="2"></font></p>
<font face="宋体" size="2">因此，在迈向高效</font><font face="Courier new" size="2">C++</font><font face="宋体" size="2">程序开发的道路上，缺省分配器的低劣性能成为一种障碍。老练的</font><font face="Courier new" size="2">C++</font><font face="宋体" size="2">程序员会尽量避免使用</font><font face="Courier new" size="2">&#8220;</font><font face="宋体" size="2">采行</font><font face="Courier new" size="2">free store</font><font face="宋体" size="2">分配行为</font><font face="Courier new" size="2">&#8221;</font><font face="宋体" size="2">的语言构件，因为根据经验他们知道它的成本高昂。缺省分配器不仅是个具体问题，还可能成为一个心理障碍。</font>
</span><br><img src ="http://www.cppblog.com/cuigang/aggbug/40932.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cuigang/" target="_blank">cuigang</a> 2008-01-10 22:54 <a href="http://www.cppblog.com/cuigang/articles/40932.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>《C++设计新思维》读书笔记（20）</title><link>http://www.cppblog.com/cuigang/articles/40931.html</link><dc:creator>cuigang</dc:creator><author>cuigang</author><pubDate>Thu, 10 Jan 2008 14:49:00 GMT</pubDate><guid>http://www.cppblog.com/cuigang/articles/40931.html</guid><wfw:comment>http://www.cppblog.com/cuigang/comments/40931.html</wfw:comment><comments>http://www.cppblog.com/cuigang/articles/40931.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/cuigang/comments/commentRss/40931.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cuigang/services/trackbacks/40931.html</trackback:ping><description><![CDATA[<span style="font-size: 10pt;"><span style="font-family: courier new;"></span><span style="font-family: courier new;">3.9 移除typelist中的某个元素</span><br style="font-family: courier new;"><br style="font-family: courier new;"><span style="font-family: courier new;">移除第一个匹配者：</span><br style="font-family: courier new;"><br style="font-family: courier new;">
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%; font-family: courier new;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #000000;">template&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;TList,&nbsp;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;T</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;Erase;<br>template&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;T</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;Erase</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">NullType,&nbsp;T</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">{<br>&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;NullType&nbsp;Result;<br>};<br>template</span><span style="color: #000000;">&lt;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;T,&nbsp;calss&nbsp;Tail</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br></span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;Erase</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">Typelist</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">T,&nbsp;Tail</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;T</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">{<br>&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;Tail&nbsp;Result;<br>};<br>template&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;Head,&nbsp;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;Tail,&nbsp;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;T</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br></span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;Erase</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">Typelist</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">Head,&nbsp;Tail</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">,&nbsp;T</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">{<br>&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;Typelist</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">Head,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typename&nbsp;Erase</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">Tail,&nbsp;T</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">::Result</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Result;<br>};</span></div>
<br style="font-family: courier new;"><br style="font-family: courier new;"><span style="font-family: courier new;">注意Erase&lt;double, int&gt;这样使用会导致编译错误。移除所有匹配者的实现如下：</span><br style="font-family: courier new;"><br style="font-family: courier new;">
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%; font-family: courier new;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #000000;">template&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;Tlist,&nbsp;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;T</span><span style="color: #000000;">&gt;</span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;EraseAll;<br>template&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;T</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;EraseAll</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">NullType,&nbsp;T</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">{<br>&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;NullType&nbsp;Result;<br>};<br>template&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;T,&nbsp;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;Tail</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br></span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;EraseAll</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">Typelist</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">T,&nbsp;Tail</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">,&nbsp;T</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">{<br>&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;typname&nbsp;EraseAll</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">Tail,&nbsp;T</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">::Result&nbsp;Result;<br>};<br>template&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;Head,&nbsp;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;Tail,&nbsp;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;T</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br></span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;EraseAll</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">Typelist</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">Head,&nbsp;Tail</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">,&nbsp;T</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">{<br>&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;Typelist</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">Head,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typename&nbsp;EraseAll</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">Tail,&nbsp;T</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">::Result</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Result;<br>};</span></div>
<br style="font-family: courier new;"><br style="font-family: courier new;"><span style="font-family: courier new;">3.10 移除重复元素（略）</span><br style="font-family: courier new;"><span style="font-family: courier new;">3.11 取代Typelist中的某个元素（略）</span><br style="font-family: courier new;"><span style="font-family: courier new;">3.12 为Typelists局部更换次序（略） </span><br><br></span><img src ="http://www.cppblog.com/cuigang/aggbug/40931.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cuigang/" target="_blank">cuigang</a> 2008-01-10 22:49 <a href="http://www.cppblog.com/cuigang/articles/40931.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>《C++设计新思维》读书笔记（19）</title><link>http://www.cppblog.com/cuigang/articles/40446.html</link><dc:creator>cuigang</dc:creator><author>cuigang</author><pubDate>Sat, 05 Jan 2008 04:19:00 GMT</pubDate><guid>http://www.cppblog.com/cuigang/articles/40446.html</guid><wfw:comment>http://www.cppblog.com/cuigang/comments/40446.html</wfw:comment><comments>http://www.cppblog.com/cuigang/articles/40446.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/cuigang/comments/commentRss/40446.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cuigang/services/trackbacks/40446.html</trackback:ping><description><![CDATA[<span style="font-size: 8pt;"><span style="font-family: courier new;"></span><span style="font-family: courier new;"></span><br style="font-family: courier new;"><span style="font-family: courier new;">3.6 索引式访问</span><span style="font-family: courier new;"></span><br style="font-family: courier new;"><br style="font-family: courier new;"><span style="font-family: courier new;">索引式访问使typelist访问线性化。象在static世界中一样，索引必须是编译期常数。一个带有索引的template声明如下：</span><span style="font-family: courier new;"></span><br style="font-family: courier new;"><br style="font-family: courier new;"><span style="font-family: courier new;">
<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;">template&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;TList,&nbsp;unsigned&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;index&nbsp;</span><span style="color: #000000;">&gt;</span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;TypeAt;</span></div>
</span><span style="font-family: courier new;"></span><br style="font-family: courier new;"><br style="font-family: courier new;"><span style="font-family: courier new;">实现如下：</span><span style="font-family: courier new;"></span><br style="font-family: courier new;"><br style="font-family: courier new;"><span style="font-family: courier new;">
<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;">template&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;Head,&nbsp;Class&nbsp;Tail</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br></span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;TypeAt</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">Typelist</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">Head,&nbsp;Tail</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">,&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">{<br>&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;Head&nbsp;Result;<br>};<br>template&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;Head,&nbsp;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;Tail,&nbsp;unsigned&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;i</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br></span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;TypeAt</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">Typelist</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">Head,&nbsp;Tail</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">,&nbsp;i</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">{<br>&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;typename&nbsp;TypeAt</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">Tail,&nbsp;i</span><span style="color: #000000;">-</span><span style="color: #000000;">1</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">::Result&nbsp;Result;<br>};<br></span></div>
</span><br style="font-family: courier new;"><span style="font-family: courier new;">如果你试着越界访问，会编译出错。对Typelist进行索引访问，花费的时间和typelist大小有关，但这个时间全部花在编译期。</span><br style="font-family: courier new;"><span style="font-family: courier new;"></span><br style="font-family: courier new;"><span style="font-family: courier new;">3.7 查找Typelist</span><span style="font-family: courier new;"></span><br style="font-family: courier new;"><br style="font-family: courier new;"><span style="font-family: courier new;">我们用IndexOf来查找Typelist中一个型别，返回其位置，找不到返回-1。</span><span style="font-family: courier new;"></span><br style="font-family: courier new;"><br style="font-family: courier new;"><span style="font-family: courier new;">
<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;">template&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;TList,&nbsp;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;T</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;IndexOf;<br>template&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;T</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br></span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;IndexOf</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">NullType,&nbsp;T</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">{<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">enum</span><span style="color: #000000;">{value&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">-</span><span style="color: #000000;">1</span><span style="color: #000000;">};<br>};<br>template&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;Tail,&nbsp;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;T</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br></span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;IndexOf</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">Typelist</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">T,&nbsp;Tail</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">,&nbsp;T</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">{<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">enum</span><span style="color: #000000;">{value&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">;}<br>};<br>template&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;Head,&nbsp;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;Tail,&nbsp;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;T</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br></span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;IndexOf</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">Typelist</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">Head,&nbsp;Tail</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">,&nbsp;T</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">{<br></span><span style="color: #0000ff;">private</span><span style="color: #000000;">:<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">enum</span><span style="color: #000000;">{temp&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;IndexOf</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">Tail,&nbsp;T</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">::vale};<br></span><span style="color: #0000ff;">public</span><span style="color: #000000;">:<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">enum</span><span style="color: #000000;">{value&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;temp&nbsp;</span><span style="color: #000000;">==</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">-</span><span style="color: #000000;">1</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">?</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">-</span><span style="color: #000000;">1</span><span style="color: #000000;">&nbsp;:&nbsp;</span><span style="color: #000000;">1</span><span style="color: #000000;">+</span><span style="color: #000000;">temp};<br>};<br></span></div>
</span><br style="font-family: courier new;"><span style="font-family: courier new;">最后一个特化版本用了问号表达式来实现分支判断。</span><span style="font-family: courier new;"></span><br style="font-family: courier new;"><br style="font-family: courier new;"><span style="font-family: courier new;">3.8 追加元素至Typelist</span><br style="font-family: courier new;"><span style="font-family: courier new;"></span><br style="font-family: courier new;"><span style="font-family: courier new;">修改typelist是不可能的，我们以by value方式传回一个新typelist。</span><span style="font-family: courier new;"></span><br style="font-family: courier new;"><br style="font-family: courier new;"><span style="font-family: courier new;">
<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;">template&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;TList,&nbsp;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;T</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;Append;<br>template&nbsp;</span><span style="color: #000000;">&lt;&gt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;Append</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">NullType,&nbsp;NullType</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">{<br>&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;NullType&nbsp;Result;<br>};<br>template&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;T</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;Append</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">NullType,&nbsp;T</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">{<br>&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;TYPELIST_1(T)&nbsp;Result;<br>};<br>template&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;Head,&nbsp;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;Tail</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br></span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;Append</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">NullType,&nbsp;Typelist</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">Head,&nbsp;Tail</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">{<br>&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;Typelist</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">Head,&nbsp;Tail</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;Result;<br>};<br>template&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;Head,&nbsp;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;Tail,&nbsp;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;T</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br></span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;Append</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">Typelist</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">Head,&nbsp;Tail</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">,&nbsp;T</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">{<br>&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;Typelist</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">Head,&nbsp;typename&nbsp;Append</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">Tail,T</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">::Result</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;Result;<br>};<br></span></div>
</span><br style="font-family: courier new;"><span style="font-family: courier new;">这个实现比较复杂，特别是最后一个偏特化版本，它递归具现Append，每次递归都将tail和待追加型别传递进去。 <br><br><br style="font-family: courier new;"></span><br></span><img src ="http://www.cppblog.com/cuigang/aggbug/40446.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cuigang/" target="_blank">cuigang</a> 2008-01-05 12:19 <a href="http://www.cppblog.com/cuigang/articles/40446.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>《C++设计新思维》读书笔记（18）</title><link>http://www.cppblog.com/cuigang/articles/40443.html</link><dc:creator>cuigang</dc:creator><author>cuigang</author><pubDate>Sat, 05 Jan 2008 04:15:00 GMT</pubDate><guid>http://www.cppblog.com/cuigang/articles/40443.html</guid><wfw:comment>http://www.cppblog.com/cuigang/comments/40443.html</wfw:comment><comments>http://www.cppblog.com/cuigang/articles/40443.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/cuigang/comments/commentRss/40443.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cuigang/services/trackbacks/40443.html</trackback:ping><description><![CDATA[<span style="font-size: 8pt; font-family: courier new;"><br>3.4 计算长度<br><br>我们用下面代码来计算typelist长度：<br>&nbsp;<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;">template&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;TList</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;Length;<br>template&nbsp;</span><span style="color: #000000;">&lt;&gt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;Length</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">NullType</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">{<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">enum</span><span style="color: #000000;">&nbsp;{&nbsp;value&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">&nbsp;};<br>};<br>template&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;T,&nbsp;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;U</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br></span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;Length</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">&nbsp;Typelist</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">T,&nbsp;U</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">{<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">enum</span><span style="color: #000000;">&nbsp;{&nbsp;value&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">1</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">&nbsp;Length</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">U</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">::value&nbsp;};<br>};</span></div>
<br><br>由Length&lt;T&gt;::value得到的值是一个编译期常数，我们可以用它来定义数组大小，<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: #000000;">std::type_info</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;intsRtti[Length</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">SignedIntegrals</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">::value];</span></div>
<br><br>这个模板代码依靠递归来完成，第一个版本是一个全特化，第二个版本是一个偏特化。<br><br>3.5 间奏曲<br><br>这里有一个问题，在上节的Length实现中，我们能否用迭代来取代递归？答案是否定的。因为我们在编译期编程中，可以使用的仅是：template、编译期整数计算、typedef。<br><br>1、templates：更明确的说是模板特化，提供编译期的if叙述。<br>2、整数计算：提供数值计算能力，用以从型别转为数值。但数值是不可改变的。<br>3、typedef：可视为用来引进&#8220;具名的型别常数&#8221;。它们也是定义之后就冻结，你不能将typedef定义的符号重新定义为另一个型别。<br><br>这些特性决定了我们无法使用迭代。所谓迭代是持有一个迭代器，并改变它，直到某些条件吻合。由于编译期我们没有&#8220;可资变化的任何东西&#8221;，所以无法实现&#8220;迭代&#8221;。所以编译期运算只能象那些纯粹函数型语言，使用大量的递归。<br></span> <img src ="http://www.cppblog.com/cuigang/aggbug/40443.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cuigang/" target="_blank">cuigang</a> 2008-01-05 12:15 <a href="http://www.cppblog.com/cuigang/articles/40443.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>《C++设计新思维》读书笔记（17）</title><link>http://www.cppblog.com/cuigang/articles/39960.html</link><dc:creator>cuigang</dc:creator><author>cuigang</author><pubDate>Sat, 29 Dec 2007 14:08:00 GMT</pubDate><guid>http://www.cppblog.com/cuigang/articles/39960.html</guid><wfw:comment>http://www.cppblog.com/cuigang/comments/39960.html</wfw:comment><comments>http://www.cppblog.com/cuigang/articles/39960.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/cuigang/comments/commentRss/39960.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cuigang/services/trackbacks/39960.html</trackback:ping><description><![CDATA[<span style="font-size: 8pt; font-family: courier new;"><br>3.2 定义Typelists<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: #008080;">1</span>&nbsp;<span style="color: #000000;"><br></span><span style="color: #008080;">2</span>&nbsp;<span style="color: #000000;">template&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;T,&nbsp;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;U</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br></span><span style="color: #008080;">3</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;Typelist<br></span><span style="color: #008080;">4</span>&nbsp;<span style="color: #000000;">{<br></span><span style="color: #008080;">5</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;T&nbsp;head;<br></span><span style="color: #008080;">6</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;U&nbsp;Tail;<br></span><span style="color: #008080;">7</span>&nbsp;<span style="color: #000000;">};</span></div>
<br><br>Typelists内部没有任何数值：它的实体是空的。它们存在的理由只是为了携带型别信息。因此，对typelist的任何处理都发生在编译期。此后我们提到一个typelist，指的是一个型别而非一个对象。虽然typlist只有两个参数，但我们可以把任意一个替换为另一个typelist，来达到无限延伸的目的。<br><br>另外我们需要一个零个型别以及一个型别的typelist。对于零个型别，前面提到的NullType就可以，对于一个型别，我们可以这样定义：<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: #008080;">1</span>&nbsp;<span style="color: #000000;">typedef&nbsp;Typelist</span><span style="color: #000000;">&lt;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">,&nbsp;NullType</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;OneTypeOnly;</span></div>
<br><br>3.3 将Typelist生成线性化<br><br>像这样一个typelist<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: #008080;">1</span><span style="color: #000000;"><br></span><span style="color: #008080;">2</span>&nbsp;<span style="color: #000000;">typedef&nbsp;Typlist</span><span style="color: #000000;">&lt;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">,&nbsp;Typelist</span><span style="color: #000000;">&lt;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">,&nbsp;Typelist</span><span style="color: #000000;">&lt;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">,&nbsp;Typelist</span><span style="color: #000000;">&lt;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">,&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;Int4Type;</span></div>
<br><br>它太Lisp了，我们定义一系列的宏来完成它，这样我们可以忘记尖括号间的空格。<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: #008080;">1</span>&nbsp;<span style="color: #0000ff;">#define</span><span style="color: #000000;">&nbsp;TYPELIST_1(T1)&nbsp;Typelist&lt;T1,&nbsp;NullType&gt;</span><span style="color: #000000;"><br></span><span style="color: #008080;">2</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">#define</span><span style="color: #000000;">&nbsp;TYPELIST_2(T1,&nbsp;T2)&nbsp;Typelist&lt;T1,&nbsp;TYPELIST_1(T2)&nbsp;&gt;</span><span style="color: #000000;"><br></span><span style="color: #008080;">3</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">#define</span><span style="color: #000000;">&nbsp;TYPELIST_3(T1,&nbsp;T2,&nbsp;T3)&nbsp;Typelist&lt;T1,&nbsp;TYPELIST_2(T2,&nbsp;T3)&nbsp;&gt;</span><span style="color: #000000;"><br></span><span style="color: #008080;">4</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">#define</span><span style="color: #000000;">&nbsp;TYPELIST_4(T1,&nbsp;T2,&nbsp;T3,&nbsp;T4)&nbsp;Typelist&lt;T1,&nbsp;TYPELIST_3(T2,&nbsp;T3,&nbsp;T4)&nbsp;&gt;</span><span style="color: #000000;"><br></span><span style="color: #008080;">5</span>&nbsp;<span style="color: #000000;"></span><span style="color: #008000;">//</span><span style="color: #008000;">etc</span><span style="color: #008000;"><br></span><span style="color: #008080;">6</span>&nbsp;<span style="color: #008000;"></span><span style="color: #0000ff;">#define</span><span style="color: #000000;">&nbsp;TYPELIST_50(/*&nbsp;*/)&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;"><img src="http://www.cppblog.com/Images/dot.gif"></span></div>
<br><br>这样前面的 Int4Type 就可以这样定义<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: #008080;">1</span>&nbsp;<span style="color: #000000;">typedef&nbsp;Int4Type&nbsp;TYPELIST_4(</span><span style="color: #0000ff;">int</span><span style="color: #000000;">,&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">,&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">,&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">)&nbsp;Int4Type;</span></div>
<br><br>这只是包装手法的一个开端。我们访问Int4Type的最后一个元素还比较麻烦，需要<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: #008080;">1</span>&nbsp;<span style="color: #000000;">Int4Type::Tail::Tail::Tail;</span></div>
<br><br>我们还要进一步来考虑它操作的问题。<br><br><br>&nbsp;<br></span><img src ="http://www.cppblog.com/cuigang/aggbug/39960.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cuigang/" target="_blank">cuigang</a> 2007-12-29 22:08 <a href="http://www.cppblog.com/cuigang/articles/39960.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>《C++设计新思维》读书笔记（16）</title><link>http://www.cppblog.com/cuigang/articles/39959.html</link><dc:creator>cuigang</dc:creator><author>cuigang</author><pubDate>Sat, 29 Dec 2007 14:05:00 GMT</pubDate><guid>http://www.cppblog.com/cuigang/articles/39959.html</guid><wfw:comment>http://www.cppblog.com/cuigang/comments/39959.html</wfw:comment><comments>http://www.cppblog.com/cuigang/articles/39959.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/cuigang/comments/commentRss/39959.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cuigang/services/trackbacks/39959.html</trackback:ping><description><![CDATA[<span style="font-size: 8pt;"><span style="font-family: courier new;"></span><br style="font-family: courier new;"><span style="font-family: courier new;">3. Typelists</span><br><br style="font-family: courier new;"><span style="font-family: courier new;">Typelists是一个用来操作一大群型别的C++工具。就像lists对数值提供各种基本操作一样，typelists对型别也提供相同操作。</span><br style="font-family: courier new;"><br style="font-family: courier new;"><span style="font-family: courier new;">有些设计模式具体指定并操作一群型别，其中也许有继承关系（但也许没有）。显著的例子是abstract factory和visitor。如果以传统编程技术来操作一大群型别，将是全然的重复工作。如此重复会导致隐微的代码膨胀。多数人不会想到其实它可以比现在更好。Typelists带给你一种能力，可以将经常性的宏工作自动化。Typelists将来自外星球的强大威力带到C++中，让它得以支持新而有趣的一些手法。</span><br style="font-family: courier new;"><br style="font-family: courier new;"><span style="font-family: courier new;">3.1 Typelists的必要性</span><br style="font-family: courier new;"><br style="font-family: courier new;"><span style="font-family: courier new;">有时候你必须针对某些型别重复撰写相同代码，而templates无法帮上忙。假如有一个abstract factory，像这样：</span><br style="font-family: courier new;"><br style="font-family: courier new;"><span style="font-family: courier new;"></span><span style="font-family: courier new;"></span>
<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: #008080;">1</span>&nbsp;<span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;WidgetFactory<br></span><span style="color: #008080;">2</span>&nbsp;<span style="color: #000000;">{<br></span><span style="color: #008080;">3</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">public</span><span style="color: #000000;">:<br></span><span style="color: #008080;">4</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">virtual</span><span style="color: #000000;">&nbsp;Window</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;CreateWindow()&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">;<br></span><span style="color: #008080;">5</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">virtual</span><span style="color: #000000;">&nbsp;Button</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;CreateButton()&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">;<br></span><span style="color: #008080;">6</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">virtual</span><span style="color: #000000;">&nbsp;ScrollBar</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;CreateScrollBar()&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">;<br></span><span style="color: #008080;">7</span>&nbsp;<span style="color: #000000;">};</span></div>
<br style="font-family: courier new;"><br style="font-family: courier new;"><span style="font-family: courier new;">如果你想将Abstract Factory概念泛化，不只生成Window、Button、ScrollBar，而是任意型别。怎么办？</span><br style="font-family: courier new;"><br style="font-family: courier new;"><span style="font-family: courier new;">如果你不试图泛化基本概念，就不太有机会泛化这些概念的具象实体。虽然抽象基类很简单，但是你会陷入无穷无尽的派生类生成器中。</span><br style="font-family: courier new;"><br style="font-family: courier new;"><span style="font-family: courier new;">我们希望能够这样去使用一个abstract factory：</span><br style="font-family: courier new;">
<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: #008080;">1</span>&nbsp;<span style="color: #000000;"><br></span><span style="color: #008080;">2</span>&nbsp;<span style="color: #000000;">template&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;T</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br></span><span style="color: #008080;">3</span>&nbsp;<span style="color: #000000;">T</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;MakeRedWidget(WidgetFactory</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">&nbsp;factory)<br></span><span style="color: #008080;">4</span>&nbsp;<span style="color: #000000;">{<br></span><span style="color: #008080;">5</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;T</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;pW&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;factory.Create</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">T</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">();<br></span><span style="color: #008080;">6</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;pW&nbsp;</span><span style="color: #000000;">-&gt;</span><span style="color: #000000;">&nbsp;SetColor(RED);<br></span><span style="color: #008080;">7</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;pW;<br></span><span style="color: #008080;">8</span>&nbsp;<span style="color: #000000;">}</span></div>
<span style="font-family: courier new;"></span><br style="font-family: courier new;"><br style="font-family: courier new;"><span style="font-family: courier new;">实际这是不可能的，如果Create不是虚函数，那么你就陷入了长长的Switch...case...之中，如果它是虚函数，那么虚函数不能是模板。</span><br style="font-family: courier new;"><span style="font-family: courier new;">Typelists将使Abstract Factories泛化成真，并带来更多其它利益。</span><br style="font-family: courier new;"><br style="font-family: courier new;"></span><img src ="http://www.cppblog.com/cuigang/aggbug/39959.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cuigang/" target="_blank">cuigang</a> 2007-12-29 22:05 <a href="http://www.cppblog.com/cuigang/articles/39959.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>《C++设计新思维》读书笔记（15）</title><link>http://www.cppblog.com/cuigang/articles/39621.html</link><dc:creator>cuigang</dc:creator><author>cuigang</author><pubDate>Tue, 25 Dec 2007 13:43:00 GMT</pubDate><guid>http://www.cppblog.com/cuigang/articles/39621.html</guid><wfw:comment>http://www.cppblog.com/cuigang/comments/39621.html</wfw:comment><comments>http://www.cppblog.com/cuigang/articles/39621.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/cuigang/comments/commentRss/39621.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cuigang/services/trackbacks/39621.html</trackback:ping><description><![CDATA[<div class="Section1"><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;" lang="EN-US"> </span></font><st1:chsdate isrocdate="False" islunardate="False" day="30" month="12" year="1899" w:st="on"><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">2.10.2</span></font></st1:chsdate><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">
</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">侦测基本型别（略）</span></font><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">'<br>2.10.3 </span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">优化的参数型别（略）<br></span></font><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">2.10.4 </span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">卸除饰词</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;" lang="EN-US"><o:p></o:p></span></font>
<p class="MsoNormal" style="text-align: left;" align="left"><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">下面是一个</span></font><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">&#8220;const
</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">卸除器</span></font><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">&#8221;</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">：</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;" lang="EN-US"><o:p></o:p></span></font></p>
<p class="MsoNormal" style="text-align: left;" align="left"><font color="green" face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;; color: green;" lang="EN-US">
<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: #008080;">&nbsp;1</span>&nbsp;<span style="color: #000000;">template</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">typename&nbsp;T</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br></span><span style="color: #008080;">&nbsp;2</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;TypeTraits<br></span><span style="color: #008080;">&nbsp;3</span>&nbsp;<span style="color: #000000;">{<br></span><span style="color: #008080;">&nbsp;4</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">private</span><span style="color: #000000;">:<br></span><span style="color: #008080;">&nbsp;5</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;template</span><span style="color: #000000;">&lt;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;U</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;UnConst<br></span><span style="color: #008080;">&nbsp;6</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span style="color: #008080;">&nbsp;7</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;U&nbsp;Result;<br></span><span style="color: #008080;">&nbsp;8</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;};<br></span><span style="color: #008080;">&nbsp;9</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;template</span><span style="color: #000000;">&lt;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;U</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;UnConst</span><span style="color: #000000;">&lt;</span><span style="color: #0000ff;">const</span><span style="color: #000000;">&nbsp;U</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br></span><span style="color: #008080;">10</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span style="color: #008080;">11</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;U&nbsp;Result;<br></span><span style="color: #008080;">12</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;};<br></span><span style="color: #008080;">13</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">public</span><span style="color: #000000;">:<br></span><span style="color: #008080;">14</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;UnConst</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">T</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">::Result&nbsp;NonConstType;<br></span><span style="color: #008080;">15</span>&nbsp;<span style="color: #000000;">};</span></div>
<br></span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;" lang="EN-US"><o:p></o:p></span></font></p>
<p class="MsoNormal" style="text-align: left;" align="left"><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;" lang="EN-US"></span></font><st1:chsdate isrocdate="False" islunardate="False" day="30" month="12" year="1899" w:st="on"><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">2.10.5</span></font></st1:chsdate><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">
</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">运用</span></font><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">TypeTraits</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;" lang="EN-US"><o:p></o:p></span></font></p>
<p class="MsoNormal" style="text-align: left;" align="left"><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">这里实作一个调用</span></font><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">BitBlast</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">的例子：</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;" lang="EN-US">&nbsp;<o:p></o:p></span></font></p>
<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: #008080;">&nbsp;<span style="font-family: courier new;">1</span></span><span style="font-family: courier new;">&nbsp;</span><span style="color: #0000ff; font-family: courier new;">enum</span><span style="color: #000000; font-family: courier new;">&nbsp;CopyAlgoSelector{Conservative,&nbsp;Fast};<br></span><span style="color: #008080; font-family: courier new;">&nbsp;2</span><span style="font-family: courier new;">&nbsp;</span><span style="color: #000000; font-family: courier new;"><br></span><span style="color: #008080; font-family: courier new;">&nbsp;3</span><span style="font-family: courier new;">&nbsp;</span><span style="color: #000000; font-family: courier new;"></span><span style="color: #008000; font-family: courier new;">//&nbsp;Conservative&nbsp;routine-works&nbsp;for&nbsp;any&nbsp;type<br></span><span style="color: #008080; font-family: courier new;">&nbsp;4</span><span style="font-family: courier new;">&nbsp;</span><span style="color: #008000; font-family: courier new;"></span><span style="color: #000000; font-family: courier new;">template&nbsp;&lt;typename&nbsp;InIt,&nbsp;typename&nbsp;OutIt&gt;<br></span><span style="color: #008080; font-family: courier new;">&nbsp;5</span><span style="font-family: courier new;">&nbsp;</span><span style="color: #000000; font-family: courier new;">OutIt&nbsp;CopyImpl(InIt&nbsp;first,&nbsp;InIt&nbsp;last,&nbsp;OutIt&nbsp;result,&nbsp;Int2Type&lt;Conservative&gt;)<br></span><span style="color: #008080; font-family: courier new;">&nbsp;6</span><span style="font-family: courier new;">&nbsp;</span><span style="color: #000000; font-family: courier new;">{<br></span><span style="color: #008080; font-family: courier new;">&nbsp;7</span><span style="font-family: courier new;">&nbsp;</span><span style="color: #000000; font-family: courier new;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff; font-family: courier new;">for</span><span style="color: #000000; font-family: courier new;">(;&nbsp;first&nbsp;!=&nbsp;last;&nbsp;++first,&nbsp;++result)<br></span><span style="color: #008080; font-family: courier new;">&nbsp;8</span><span style="font-family: courier new;">&nbsp;</span><span style="color: #000000; font-family: courier new;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*result&nbsp;=&nbsp;*first;<br></span><span style="color: #008080; font-family: courier new;">&nbsp;9</span><span style="font-family: courier new;">&nbsp;</span><span style="color: #000000; font-family: courier new;">}<br></span><span style="color: #008080; font-family: courier new;">10</span><span style="font-family: courier new;">&nbsp;</span><span style="color: #000000; font-family: courier new;"><br></span><span style="color: #008080; font-family: courier new;">11</span><span style="font-family: courier new;">&nbsp;</span><span style="color: #000000; font-family: courier new;"></span><span style="color: #008000; font-family: courier new;">//&nbsp;Fast&nbsp;routine-works&nbsp;only&nbsp;for&nbsp;pointers&nbsp;to&nbsp;raw&nbsp;data<br></span><span style="color: #008080; font-family: courier new;">12</span><span style="font-family: courier new;">&nbsp;</span><span style="color: #008000; font-family: courier new;"></span><span style="color: #000000; font-family: courier new;">template&nbsp;&lt;typename&nbsp;InIt,&nbsp;typename&nbsp;OutIt&gt;<br></span><span style="color: #008080; font-family: courier new;">13</span><span style="font-family: courier new;">&nbsp;</span><span style="color: #000000; font-family: courier new;">OutIt&nbsp;CopyImpl(InIt&nbsp;first,&nbsp;InIt&nbsp;last,&nbsp;OutIt&nbsp;result,&nbsp;Int2Type&lt;Fast&gt;)<br></span><span style="color: #008080; font-family: courier new;">14</span><span style="font-family: courier new;">&nbsp;</span><span style="color: #000000; font-family: courier new;">{<br></span><span style="color: #008080; font-family: courier new;">15</span><span style="font-family: courier new;">&nbsp;</span><span style="color: #000000; font-family: courier new;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff; font-family: courier new;">const</span><span style="color: #000000; font-family: courier new;">&nbsp;size_t&nbsp;n&nbsp;=&nbsp;last&nbsp;-&nbsp;first;<br></span><span style="color: #008080; font-family: courier new;">16</span><span style="font-family: courier new;">&nbsp;</span><span style="color: #000000; font-family: courier new;">&nbsp;&nbsp;&nbsp;&nbsp;BitBlast(first,&nbsp;result,&nbsp;n&nbsp;*&nbsp;</span><span style="color: #0000ff; font-family: courier new;">sizeof</span><span style="color: #000000; font-family: courier new;">(*first));<br></span><span style="color: #008080; font-family: courier new;">17</span><span style="font-family: courier new;">&nbsp;</span><span style="color: #000000; font-family: courier new;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff; font-family: courier new;">return</span><span style="color: #000000; font-family: courier new;">&nbsp;result&nbsp;+&nbsp;n;<br></span><span style="color: #008080; font-family: courier new;">18</span><span style="font-family: courier new;">&nbsp;</span><span style="color: #000000; font-family: courier new;">}<br></span><span style="color: #008080; font-family: courier new;">19</span><span style="font-family: courier new;">&nbsp;</span><span style="color: #000000; font-family: courier new;"><br></span><span style="color: #008080; font-family: courier new;">20</span><span style="font-family: courier new;">&nbsp;</span><span style="color: #000000; font-family: courier new;">template&lt;typename&nbsp;T&gt;&nbsp;</span><span style="color: #0000ff; font-family: courier new;">struct</span><span style="color: #000000; font-family: courier new;">&nbsp;SupportsBitwiseCopy<br></span><span style="color: #008080; font-family: courier new;">21</span><span style="font-family: courier new;">&nbsp;</span><span style="color: #000000; font-family: courier new;">{<br></span><span style="color: #008080; font-family: courier new;">22</span><span style="font-family: courier new;">&nbsp;</span><span style="color: #000000; font-family: courier new;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff; font-family: courier new;">enum</span><span style="color: #000000; font-family: courier new;">{result&nbsp;=&nbsp;TypeTraits&lt;T&gt;::isStdFundamental};<br></span><span style="color: #008080; font-family: courier new;">23</span><span style="font-family: courier new;">&nbsp;</span><span style="color: #000000; font-family: courier new;">}<br></span><span style="color: #008080; font-family: courier new;">24</span><span style="font-family: courier new;">&nbsp;</span><span style="color: #000000; font-family: courier new;"><br></span><span style="color: #008080; font-family: courier new;">25</span><span style="font-family: courier new;">&nbsp;</span><span style="color: #000000; font-family: courier new;">template&nbsp;&lt;typename&nbsp;InIt,&nbsp;typename&nbsp;OutIt&gt;<br></span><span style="color: #008080; font-family: courier new;">26</span><span style="font-family: courier new;">&nbsp;</span><span style="color: #000000; font-family: courier new;">OutIt&nbsp;Copy(InIt&nbsp;first,&nbsp;InIt&nbsp;last,&nbsp;OutIt&nbsp;result)<br></span><span style="color: #008080; font-family: courier new;">27</span><span style="font-family: courier new;">&nbsp;</span><span style="color: #000000; font-family: courier new;">{<br></span><span style="color: #008080; font-family: courier new;">28</span><span style="font-family: courier new;">&nbsp;</span><span style="color: #000000; font-family: courier new;">&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;TypeTraits&lt;InIt&gt;::PointeeType&nbsp;SrcPointee;<br></span><span style="color: #008080; font-family: courier new;">29</span><span style="font-family: courier new;">&nbsp;</span><span style="color: #000000; font-family: courier new;">&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;TypeTraits&lt;OutIt&gt;::PointeeType&nbsp;DestPointee;<br></span><span style="color: #008080; font-family: courier new;">30</span><span style="font-family: courier new;">&nbsp;</span><span style="color: #000000; font-family: courier new;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff; font-family: courier new;">enum</span><span style="color: #000000; font-family: courier new;">&nbsp;{&nbsp;copyAlgo&nbsp;=<br></span><span style="color: #008080; font-family: courier new;">31</span><span style="font-family: courier new;">&nbsp;</span><span style="color: #000000; font-family: courier new;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TypeTraits&lt;InIt&gt;::IsPointer&nbsp;&amp;&amp;<br></span><span style="color: #008080; font-family: courier new;">32</span><span style="font-family: courier new;">&nbsp;</span><span style="color: #000000; font-family: courier new;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TypeTraits&lt;OutIt&gt;::IsPointer&nbsp;&amp;&amp;<br></span><span style="color: #008080; font-family: courier new;">33</span><span style="font-family: courier new;">&nbsp;</span><span style="color: #000000; font-family: courier new;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SupportsBitwiseCopy&lt;SrcPointee&gt;::result&nbsp;&amp;&amp;<br></span><span style="color: #008080; font-family: courier new;">34</span><span style="font-family: courier new;">&nbsp;</span><span style="color: #000000; font-family: courier new;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SupportsBitwiseCopy&lt;DestPointee&gt;::result&nbsp;&amp;&amp;<br></span><span style="color: #008080; font-family: courier new;">35</span><span style="font-family: courier new;">&nbsp;</span><span style="color: #000000; font-family: courier new;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff; font-family: courier new;">sizeof</span><span style="color: #000000; font-family: courier new;">(SrcPointee)&nbsp;==&nbsp;</span><span style="color: #0000ff; font-family: courier new;">sizeof</span><span style="color: #000000; font-family: courier new;">(DestPointee)&nbsp;};<br></span><span style="color: #008080; font-family: courier new;">36</span><span style="font-family: courier new;">&nbsp;</span><span style="color: #000000; font-family: courier new;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff; font-family: courier new;">return</span><span style="color: #000000; font-family: courier new;">&nbsp;CopyImpl(first,&nbsp;last,&nbsp;Int2Type&lt;useBitBlast&gt;);<br></span><span style="color: #008080; font-family: courier new;">37</span><span style="font-family: courier new;">&nbsp;</span><span style="color: #000000; font-family: courier new;">}</span></div>
<br>
<p class="MsoNormal" style="text-align: left;" align="left"><font color="green" face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;; color: green;" lang="EN-US"></span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;" lang="EN-US"><o:p></o:p></span></font></p>
<p class="MsoNormal" style="text-align: left;" align="left"><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">对于一个</span></font><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">POD</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">结构（</span></font><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">plain old data</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">），即</span></font><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">C
struct</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">，只有数据没有其它任何东西。因为无法甄别其类型，会调用慢速版本。我们可以这样做，让它调用快速版本，假如</span></font><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">POD</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">结构为</span></font><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">Mytype</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">。</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;" lang="EN-US"><o:p></o:p></span></font></p>
<p class="MsoNormal" style="text-align: left;" align="left"><font color="green" face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;; color: green;" lang="EN-US">
<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: #008080;">1</span>&nbsp;<span style="color: #000000;">template</span><span style="color: #000000;">&lt;&gt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;SupportsBitwiseCopy</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">MyTyee</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br></span><span style="color: #008080;">2</span>&nbsp;<span style="color: #000000;">{<br></span><span style="color: #008080;">3</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">enum</span><span style="color: #000000;">&nbsp;{result&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">true</span><span style="color: #000000;">};<br></span><span style="color: #008080;">4</span>&nbsp;<span style="color: #000000;">};</span></div>
<br></span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;" lang="EN-US"><o:p></o:p></span></font></p>
</div><img src ="http://www.cppblog.com/cuigang/aggbug/39621.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cuigang/" target="_blank">cuigang</a> 2007-12-25 21:43 <a href="http://www.cppblog.com/cuigang/articles/39621.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>《C++设计新思维》读书笔记（14）</title><link>http://www.cppblog.com/cuigang/articles/39533.html</link><dc:creator>cuigang</dc:creator><author>cuigang</author><pubDate>Mon, 24 Dec 2007 13:55:00 GMT</pubDate><guid>http://www.cppblog.com/cuigang/articles/39533.html</guid><wfw:comment>http://www.cppblog.com/cuigang/comments/39533.html</wfw:comment><comments>http://www.cppblog.com/cuigang/articles/39533.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/cuigang/comments/commentRss/39533.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cuigang/services/trackbacks/39533.html</trackback:ping><description><![CDATA[<st1:chsdate isrocdate="False" islunardate="False" day="30" month="12" year="1899" w:st="on"><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">2.10.1</span></font></st1:chsdate><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">
</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">实作出</span></font><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">Pointer Traits</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;" lang="EN-US"><o:p></o:p></span></font>
<p class="MsoNormal" style="text-align: left;" align="left"><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">大部分</span></font><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">type
traits</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">的实作都依赖全特化或偏特化。下面代码用来判断型别</span></font><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">T</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">是否为指针：</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;" lang="EN-US"><o:p></o:p></span></font></p>
<p class="MsoNormal" style="text-align: left;" align="left"><font face="宋体" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;; color: green;" lang="EN-US">
<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: #008080;">&nbsp;1</span>&nbsp;<span style="color: #000000;">template</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">typename&nbsp;T</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br></span><span style="color: #008080;">&nbsp;2</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;TypeTraits<br></span><span style="color: #008080;">&nbsp;3</span>&nbsp;<span style="color: #000000;">{<br></span><span style="color: #008080;">&nbsp;4</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">private</span><span style="color: #000000;">:<br></span><span style="color: #008080;">&nbsp;5</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;template</span><span style="color: #000000;">&lt;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;U</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;PointerTraits<br></span><span style="color: #008080;">&nbsp;6</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span style="color: #008080;">&nbsp;7</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">enum</span><span style="color: #000000;">&nbsp;{&nbsp;result&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">false</span><span style="color: #000000;">&nbsp;};<br></span><span style="color: #008080;">&nbsp;8</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;NullType&nbsp;PointeeType;<br></span><span style="color: #008080;">&nbsp;9</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;};<br></span><span style="color: #008080;">10</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;template</span><span style="color: #000000;">&lt;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;U</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;PointerTraits</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">U</span><span style="color: #000000;">*&gt;</span><span style="color: #000000;"><br></span><span style="color: #008080;">11</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span style="color: #008080;">12</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">enum</span><span style="color: #000000;">&nbsp;{&nbsp;result&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">true</span><span style="color: #000000;">&nbsp;};<br></span><span style="color: #008080;">13</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;U&nbsp;PointeeType;<br></span><span style="color: #008080;">14</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;};<br></span><span style="color: #008080;">15</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">public</span><span style="color: #000000;">:<br></span><span style="color: #008080;">16</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">enum</span><span style="color: #000000;">&nbsp;{&nbsp;isPointer&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;PointerTraits</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">T</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">::result&nbsp;};<br></span><span style="color: #008080;">17</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;PointerTraits</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">T</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">::Pointeetype&nbsp;PointeeType;<br></span><span style="color: #008080;">18</span>&nbsp;<span style="color: #000000;">};</span></div>
<br></span><br><span style="font-size: 9pt; font-family: 宋体;">对于一个指针型别，</span></font><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">PointerTraits</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">的偏特化版本更适合。所以对于一个非指针型别，</span></font><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">result</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">为</span></font><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">false</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">，所谓被指型别</span></font><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">PointeeType</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">不能拿来使用，只是一个不能被使用的占位型别（</span></font><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">placeholder type</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">）。</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;" lang="EN-US"><o:p></o:p></span></font></p>
<p class="MsoNormal" style="text-align: left;" align="left"><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">对于指向成员函数的指针，我们需要这样做：</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;" lang="EN-US"><o:p></o:p></span></font></p>
<font color="green" face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;; color: green;" lang="EN-US">
<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: #008080;">&nbsp;1</span>&nbsp;<span style="color: #000000;">template</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">typename&nbsp;T</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br></span><span style="color: #008080;">&nbsp;2</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;TypeTraits<br></span><span style="color: #008080;">&nbsp;3</span>&nbsp;<span style="color: #000000;">{<br></span><span style="color: #008080;">&nbsp;4</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">private</span><span style="color: #000000;">:<br></span><span style="color: #008080;">&nbsp;5</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;template&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;U</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;PToMTraits<br></span><span style="color: #008080;">&nbsp;6</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span style="color: #008080;">&nbsp;7</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">enum</span><span style="color: #000000;">{result&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">false</span><span style="color: #000000;">};<br></span><span style="color: #008080;">&nbsp;8</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;};<br></span><span style="color: #008080;">&nbsp;9</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;template&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;U,&nbsp;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;V</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br></span><span style="color: #008080;">10</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;PToMTraits</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">U,&nbsp;V::</span><span style="color: #000000;">*&gt;</span><span style="color: #000000;"><br></span><span style="color: #008080;">11</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span style="color: #008080;">12</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">enum</span><span style="color: #000000;">&nbsp;{reulst&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">true</span><span style="color: #000000;">&nbsp;};<br></span><span style="color: #008080;">13</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;}<br></span><span style="color: #008080;">14</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">public</span><span style="color: #000000;">:<br></span><span style="color: #008080;">15</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">enum</span><span style="color: #000000;">&nbsp;{&nbsp;isMemberPointer&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;PToMTraits</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">T</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">::result};<br></span><span style="color: #008080;">16</span>&nbsp;<span style="color: #000000;">};<br></span><span style="color: #008080;">17</span>&nbsp;<span style="color: #000000;"></span></div>
<br></span></font><img src ="http://www.cppblog.com/cuigang/aggbug/39533.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cuigang/" target="_blank">cuigang</a> 2007-12-24 21:55 <a href="http://www.cppblog.com/cuigang/articles/39533.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>《C++设计新思维》读书笔记（13）</title><link>http://www.cppblog.com/cuigang/articles/39344.html</link><dc:creator>cuigang</dc:creator><author>cuigang</author><pubDate>Sun, 23 Dec 2007 04:14:00 GMT</pubDate><guid>http://www.cppblog.com/cuigang/articles/39344.html</guid><wfw:comment>http://www.cppblog.com/cuigang/comments/39344.html</wfw:comment><comments>http://www.cppblog.com/cuigang/articles/39344.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/cuigang/comments/commentRss/39344.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cuigang/services/trackbacks/39344.html</trackback:ping><description><![CDATA[<div class="Section1"><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;" lang="EN-US"></span></font><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">2.8
type_info</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">的一个外覆类（</span></font><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">Wrapper</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">）</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;" lang="EN-US"><o:p></o:p></span></font>
<p class="MsoNormal" style="text-align: left;" align="left"><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">因为</span></font><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">std::type_info</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">类不太好用，作者提供的</span></font><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">Loki</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">库对其包装了一下，这节对其进行介绍，省去。</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;" lang="EN-US"><o:p></o:p></span></font></p>
<p class="MsoNormal" style="text-align: left;" align="left"><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">2.9
NullType </span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">和</span></font><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US"> EmptyType</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;" lang="EN-US"><o:p></o:p></span></font></p>
<p class="MsoNormal" style="text-align: left;" align="left"><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">Loki</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">定义了两个非常简单的型别：</span></font><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">NullType </span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">和</span></font><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">
EmptyType</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">。可以作为型别计算的边界。</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;" lang="EN-US"><o:p></o:p></span></font></p>
<p class="MsoNormal" style="text-align: left;" align="left"><font color="green" face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;; color: green;" lang="EN-US">
<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: #008080;">1</span>&nbsp;<span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;NullType;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">没有定义</span><span style="color: #008000;"><br></span><span style="color: #008080;">2</span>&nbsp;<span style="color: #008000;"></span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;EmptyType{};</span></div>
<br></span></font><font color="green" face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;; color: green;" lang="EN-US"></span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;" lang="EN-US"><o:p></o:p></span></font></p>
<p class="MsoNormal" style="text-align: left;" align="left"><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">第</span></font><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">3</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">章会展示其用途。</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;" lang="EN-US"><o:p></o:p></span></font></p>
<p class="MsoNormal" style="text-align: left;" align="left"><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">2.10
Type Traits</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;" lang="EN-US"><o:p></o:p></span></font></p>
<p class="MsoNormal" style="text-align: left;" align="left"><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">Traits
</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">是一种</span></font><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">&#8220;</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">可于编译期根据型别作判断</span></font><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">&#8221;</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">的泛型技术，很想你在执行期根据数值进行判断一样。假设你想实作</span></font><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">
Copying</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">算法：</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;" lang="EN-US"><o:p></o:p></span></font></p>
<p class="MsoNormal" style="text-align: left;" align="left"><font color="green" face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;; color: green;" lang="EN-US">
<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: #008080;">1</span>&nbsp;<span style="color: #000000;">template&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">typename&nbsp;InIt,&nbsp;typename&nbsp;OutIt</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br></span><span style="color: #008080;">2</span>&nbsp;<span style="color: #000000;">OutIt&nbsp;Copy(InIt&nbsp;first,&nbsp;InIt&nbsp;last,&nbsp;OutIt&nbsp;result)<br></span><span style="color: #008080;">3</span>&nbsp;<span style="color: #000000;">{<br></span><span style="color: #008080;">4</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">for</span><span style="color: #000000;">(;&nbsp;fist</span><span style="color: #000000;">!=</span><span style="color: #000000;">last;&nbsp;</span><span style="color: #000000;">++</span><span style="color: #000000;">first,&nbsp;</span><span style="color: #000000;">++</span><span style="color: #000000;">result)<br></span><span style="color: #008080;">5</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">result&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">first;<br></span><span style="color: #008080;">6</span>&nbsp;<span style="color: #000000;">}</span></div>
<br></span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;" lang="EN-US"><o:p></o:p></span></font></p>
<p class="MsoNormal" style="text-align: left;" align="left"><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">另外假设你有一个针对硬件优化的非常快的内建函数，你希望尽可能发挥改函数的好处。</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;" lang="EN-US">&nbsp;<o:p></o:p></span></font></p>
<p class="MsoNormal" style="text-align: left;" align="left"><font color="green" face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;; color: green;" lang="EN-US">
<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: #008080;">1</span>&nbsp;<span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;BitBlast(</span><span style="color: #0000ff;">const</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;src,&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;dest,&nbsp;size_t&nbsp;bytes);</span></div>
<br></span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;" lang="EN-US"><o:p></o:p></span></font></p>
<p class="MsoNormal" style="text-align: left;" align="left"><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">这是一个只针对基本型别并有着简朴旧式结构的实作，你不能将它用于拥有</span></font><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">&#8220;nontrivial copy</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">构造函数</span></font><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">&#8221;</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">的型别上。你可能需要对型别判断，以判断是否可以利用</span></font><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">BitBlast</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">，以便对基本型别快速执行。</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;" lang="EN-US"><o:p></o:p></span></font></p>
<p class="MsoNormal" style="text-align: left;" align="left"><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">你需要判断：</span></font><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US"><br>
1</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">、</span></font><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">InIt </span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">和</span></font><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US"> OutIt</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">是一般指针吗？（针对</span></font><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">iterator</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">迭代器而言）</span></font><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US"><br>
2</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">、</span></font><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">InIt </span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">和</span></font><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US"> OutIt</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">所指的型别可以</span></font><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">bitwise copy</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">（位逐一拷贝）吗？</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;" lang="EN-US"><o:p></o:p></span></font></p>
<p class="MsoNormal" style="text-align: left;" align="left"><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">Type
traits </span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">有助于解决这样的问题。</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;" lang="EN-US"><o:p></o:p></span></font></p>
</div><img src ="http://www.cppblog.com/cuigang/aggbug/39344.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cuigang/" target="_blank">cuigang</a> 2007-12-23 12:14 <a href="http://www.cppblog.com/cuigang/articles/39344.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>《C++设计新思维》读书笔记（12）</title><link>http://www.cppblog.com/cuigang/articles/39343.html</link><dc:creator>cuigang</dc:creator><author>cuigang</author><pubDate>Sun, 23 Dec 2007 04:12:00 GMT</pubDate><guid>http://www.cppblog.com/cuigang/articles/39343.html</guid><wfw:comment>http://www.cppblog.com/cuigang/comments/39343.html</wfw:comment><comments>http://www.cppblog.com/cuigang/articles/39343.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/cuigang/comments/commentRss/39343.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cuigang/services/trackbacks/39343.html</trackback:ping><description><![CDATA[<div class="Section1"><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">2.7
</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">编译期间侦测可转换性和继承性</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;" lang="EN-US"><o:p></o:p></span></font>
<p class="MsoNormal" style="text-align: left;" align="left"><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">在泛型编程中，经常遭遇一个问题：对于两个型别</span></font><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">T</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">和</span></font><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">U</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">，如何得知</span></font><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">U</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">是否继承于</span></font><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">T</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">。我们需要在编译时发现这样的关系，而不必使用</span></font><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">dynamic_cast——</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">它会损耗执行期效率。</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;" lang="EN-US"><o:p></o:p></span></font></p>
<p class="MsoNormal" style="text-align: left;" align="left"><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">我们利用</span></font><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">sizeof
</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">和</span></font><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;Courier New&quot;;"> </span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">重载函数。比如如下定义两个类型，和两个函数，一个函数接收</span></font><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">U</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">类型，一个接收任意类型。</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;" lang="EN-US"><o:p></o:p></span></font></p>
<p class="MsoNormal" style="text-align: left;" align="left"><font color="green" face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;; color: green;" lang="EN-US">
<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: #008080;">1</span>&nbsp;<span style="color: #000000;">typedef&nbsp;</span><span style="color: #0000ff;">char</span><span style="color: #000000;">&nbsp;Small;<br></span><span style="color: #008080;">2</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;Big&nbsp;{</span><span style="color: #0000ff;">char</span><span style="color: #000000;">&nbsp;dummy[</span><span style="color: #000000;">2</span><span style="color: #000000;">];};<br></span><span style="color: #008080;">3</span>&nbsp;<span style="color: #000000;">Small&nbsp;Test(U);<br></span><span style="color: #008080;">4</span>&nbsp;<span style="color: #000000;">Big&nbsp;Test(<img src="http://www.cppblog.com/Images/dot.gif">);</span><span style="color: #008000;">//</span><span style="color: #008000;">省略号参数函数</span></div>
<br></span></font><font color="green" face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体; color: green;"></span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;" lang="EN-US"><o:p></o:p></span></font></p>
<p class="MsoNormal" style="text-align: left;" align="left"><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">我们传一个</span></font><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">T</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">类型对象给</span></font><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">Test</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">函数，看它能不能转换为</span></font><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">U</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">：</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;" lang="EN-US"><o:p></o:p></span></font></p>
<p class="MsoNormal" style="text-align: left;" align="left"><font color="green" face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;; color: green;" lang="EN-US">
<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: #008080;">1</span>&nbsp;<span style="color: #0000ff;">const</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">bool</span><span style="color: #000000;">&nbsp;convExists&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">sizeof</span><span style="color: #000000;">(Test(T()))&nbsp;</span><span style="color: #000000;">==</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">sizeof</span><span style="color: #000000;">(Small);</span></div>
<br></span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;" lang="EN-US"><o:p></o:p></span></font></p>
<p class="MsoNormal" style="text-align: left;" align="left"><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">但如果</span></font><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">T</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">的缺省构造函数为私有，则会编译失败，所以我们用一个</span></font><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">&#8220;</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">稻草人函数</span></font><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">&#8221;</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">：</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;" lang="EN-US"><o:p></o:p></span></font></p>
<p class="MsoNormal" style="text-align: left;" align="left"><font color="green" face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;; color: green;" lang="EN-US">
<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: #008080;">1</span>&nbsp;<span style="color: #000000;">T&nbsp;MakeT();<br></span><span style="color: #008080;">2</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">const</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">bool</span><span style="color: #000000;">&nbsp;convExists&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">sizeof</span><span style="color: #000000;">(Test(MakeT()))&nbsp;</span><span style="color: #000000;">==</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">sizeof</span><span style="color: #000000;">(Small);</span></div>
<br></span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;" lang="EN-US"><o:p></o:p></span></font></p>
<p class="MsoNormal" style="text-align: left;" align="left"><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">我们注意，</span></font><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">sizeof()</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">里面的东西不需要具现，所以</span></font><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">T</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">对象，</span></font><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">MakeT()</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">、</span></font><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">Test()</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">都不需要实作。它们根本不真正存在！！现在用</span></font><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">class
template</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">包装起来。</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;" lang="EN-US"><o:p></o:p></span></font></p>
<p class="MsoNormal" style="text-align: left;" align="left"><font color="green" face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;; color: green;" lang="EN-US">
<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: #008080;">&nbsp;1</span>&nbsp;<span style="color: #000000;">template</span><span style="color: #000000;">&lt;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;T,&nbsp;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;U</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br></span><span style="color: #008080;">&nbsp;2</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;Conversion<br></span><span style="color: #008080;">&nbsp;3</span>&nbsp;<span style="color: #000000;">{<br></span><span style="color: #008080;">&nbsp;4</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;</span><span style="color: #0000ff;">char</span><span style="color: #000000;">&nbsp;Small;<br></span><span style="color: #008080;">&nbsp;5</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;Big&nbsp;{</span><span style="color: #0000ff;">char</span><span style="color: #000000;">&nbsp;dummy[</span><span style="color: #000000;">2</span><span style="color: #000000;">];};<br></span><span style="color: #008080;">&nbsp;6</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">static</span><span style="color: #000000;">&nbsp;Small&nbsp;Test(U);<br></span><span style="color: #008080;">&nbsp;7</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">static</span><span style="color: #000000;">&nbsp;Big&nbsp;Test(<img src="http://www.cppblog.com/Images/dot.gif">);<br></span><span style="color: #008080;">&nbsp;8</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">static</span><span style="color: #000000;">&nbsp;T&nbsp;MakeT();<br></span><span style="color: #008080;">&nbsp;9</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">public</span><span style="color: #000000;">:<br></span><span style="color: #008080;">10</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;T可以转换为U</span><span style="color: #008000;"><br></span><span style="color: #008080;">11</span>&nbsp;<span style="color: #008000;"></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">enum</span><span style="color: #000000;">&nbsp;{exists&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">sizeof</span><span style="color: #000000;">(Test(MakeT()))&nbsp;</span><span style="color: #000000;">==</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">sizeof</span><span style="color: #000000;">(Small)};<br></span><span style="color: #008080;">12</span>&nbsp;<span style="color: #000000;">&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: #008080;">13</span>&nbsp;<span style="color: #008000;"></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">enum</span><span style="color: #000000;">&nbsp;{exists2Way&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;exists&nbsp;</span><span style="color: #000000;">&amp;&amp;</span><span style="color: #000000;">&nbsp;conversion</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">U,&nbsp;T</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">::exists&nbsp;};<br></span><span style="color: #008080;">14</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">enum</span><span style="color: #000000;">&nbsp;{sameType&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">false</span><span style="color: #000000;">};<br></span><span style="color: #008080;">15</span>&nbsp;<span style="color: #000000;">};<br></span><span style="color: #008080;">16</span>&nbsp;<span style="color: #000000;"></span><span style="color: #008000;">//</span><span style="color: #008000;">利用偏特化处理&nbsp;sameType&nbsp;==&nbsp;true&nbsp;情况</span><span style="color: #008000;"><br></span><span style="color: #008080;">17</span>&nbsp;<span style="color: #008000;"></span><span style="color: #000000;">template</span><span style="color: #000000;">&lt;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;T</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br></span><span style="color: #008080;">18</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;Conversion</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">T,&nbsp;T</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br></span><span style="color: #008080;">19</span>&nbsp;<span style="color: #000000;">{<br></span><span style="color: #008080;">20</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">public</span><span style="color: #000000;">:<br></span><span style="color: #008080;">21</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">enum</span><span style="color: #000000;">&nbsp;{&nbsp;exists&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">1</span><span style="color: #000000;">,&nbsp;exists2Way&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">1</span><span style="color: #000000;">,&nbsp;sameType&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">1</span><span style="color: #000000;">};<br></span><span style="color: #008080;">22</span>&nbsp;<span style="color: #000000;">};</span></div>
<br></span></font><font color="green" face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;; color: green;" lang="EN-US"></span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;" lang="EN-US"><o:p></o:p></span></font></p>
<p class="MsoNormal" style="text-align: left;" align="left"><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">最后，我们可以根据这个来判断两个类之间是否有继承关系：</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;" lang="EN-US"><o:p></o:p></span></font></p>
<p class="MsoNormal" style="text-align: left;" align="left"><font color="green" face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;; color: green;" lang="EN-US">
<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: #008080;">1</span>&nbsp;<span style="color: #0000ff;">#define</span><span style="color: #000000;">&nbsp;SUPER_SUB_CLASS(T,&nbsp;U)\</span><span style="color: #000000;"><br></span><span style="color: #008080;">2</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(Conversion</span><span style="color: #000000;">&lt;</span><span style="color: #0000ff;">const</span><span style="color: #000000;">&nbsp;U</span><span style="color: #000000;">*</span><span style="color: #000000;">,&nbsp;</span><span style="color: #0000ff;">const</span><span style="color: #000000;">&nbsp;T</span><span style="color: #000000;">*&gt;</span><span style="color: #000000;">::exists&nbsp;</span><span style="color: #000000;">&amp;&amp;</span><span style="color: #000000;">\<br></span><span style="color: #008080;">3</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000;">!</span><span style="color: #000000;">Conversion</span><span style="color: #000000;">&lt;</span><span style="color: #0000ff;">const</span><span style="color: #000000;">&nbsp;T</span><span style="color: #000000;">*</span><span style="color: #000000;">,&nbsp;</span><span style="color: #0000ff;">const</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">*&gt;</span><span style="color: #000000;">::sameType)</span></div>
<br></span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;" lang="EN-US"><o:p></o:p></span></font></p>
<p class="MsoNormal" style="text-align: left;" align="left"><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">如果</span></font><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">U</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">是共有继承于</span></font><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">T</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">，或者</span></font><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">T</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">和</span></font><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">U</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">是同一型别，</span></font><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">SUPER_SUB_CLASS(T,
U)</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">都传回</span></font><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">true</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">。这里加上</span></font><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">const</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">饰词的原因是，我们不希望因</span></font><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">const</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">而导致转换失败，对一个型别</span></font><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">const</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">两次，第二个</span></font><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">const</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">会被忽略。</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;" lang="EN-US"><o:p></o:p></span></font></p>
</div><img src ="http://www.cppblog.com/cuigang/aggbug/39343.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cuigang/" target="_blank">cuigang</a> 2007-12-23 12:12 <a href="http://www.cppblog.com/cuigang/articles/39343.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>《C++设计新思维》读书笔记（11）</title><link>http://www.cppblog.com/cuigang/articles/39162.html</link><dc:creator>cuigang</dc:creator><author>cuigang</author><pubDate>Thu, 20 Dec 2007 14:00:00 GMT</pubDate><guid>http://www.cppblog.com/cuigang/articles/39162.html</guid><wfw:comment>http://www.cppblog.com/cuigang/comments/39162.html</wfw:comment><comments>http://www.cppblog.com/cuigang/articles/39162.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/cuigang/comments/commentRss/39162.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cuigang/services/trackbacks/39162.html</trackback:ping><description><![CDATA[<div class="Section1"><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;" lang="EN-US"></span></font><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">2.6
</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">型别选择</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;" lang="EN-US"><o:p></o:p></span></font><br>
<p class="MsoNormal" style="text-align: left;" align="left"><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;" lang="EN-US">
</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">有时候，泛型程序需要根据一个</span></font><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">bool</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">量来选择某个型别。</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;" lang="EN-US"><o:p></o:p></span></font></p>
<p class="MsoNormal" style="text-align: left;" align="left"><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">假如对</span></font><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">NiftyContainer</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">，你需要一个</span></font><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">std::vector</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">作为后端存储结构。那么可能对于多态型别，你不能存储实体，只能存储指针。而对于非多态型别，你可以存储实体，因为这样有效率。</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;" lang="EN-US"><o:p></o:p></span></font></p>
<p class="MsoNormal" style="text-align: left;" align="left"><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">在你的</span></font><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">class
template</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">中：</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;" lang="EN-US"><o:p></o:p></span></font></p>
<p class="MsoNormal" style="text-align: left;" align="left"><font color="green" face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;; color: green;" lang="EN-US">
<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: #008080;">1</span>&nbsp;<span style="color: #000000;">template&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">typename&nbsp;T,&nbsp;</span><span style="color: #0000ff;">bool</span><span style="color: #000000;">&nbsp;isPolymorphic</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br></span><span style="color: #008080;">2</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;NiftyContainer<br></span><span style="color: #008080;">3</span>&nbsp;<span style="color: #000000;">{<br></span><span style="color: #008080;">4</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;"><img src="http://www.cppblog.com/Images/dot.gif"></span><span style="color: #008000;"><br></span><span style="color: #008080;">5</span>&nbsp;<span style="color: #008000;"></span><span style="color: #000000;">};</span></div>
<br></span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;" lang="EN-US"><o:p></o:p></span></font></p>
<p class="MsoNormal" style="text-align: left;" align="left"><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">你要放一个</span></font><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">
vector&lt;T*&gt; </span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">或者</span></font><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US"> vector&lt;T&gt;</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">。根据</span></font><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">isPolymorphic</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">来定，你可以使用</span></font><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">
traits class template </span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">如下：</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;" lang="EN-US"><o:p></o:p></span></font></p>
<p class="MsoNormal" style="text-align: left;" align="left"><font color="green" face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;; color: green;" lang="EN-US">
<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: #008080;">&nbsp;1</span>&nbsp;<span style="color: #000000;">template&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">typename&nbsp;T,&nbsp;</span><span style="color: #0000ff;">bool</span><span style="color: #000000;">&nbsp;isPolymorphoic</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br></span><span style="color: #008080;">&nbsp;2</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;NiftyContainerValueTraits<br></span><span style="color: #008080;">&nbsp;3</span>&nbsp;<span style="color: #000000;">{<br></span><span style="color: #008080;">&nbsp;4</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;T</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;ValueType;<br></span><span style="color: #008080;">&nbsp;5</span>&nbsp;<span style="color: #000000;">};<br></span><span style="color: #008080;">&nbsp;6</span>&nbsp;<span style="color: #000000;">template&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">typename&nbsp;T</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br></span><span style="color: #008080;">&nbsp;7</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;NiftyContainerValueTraits</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">T,&nbsp;</span><span style="color: #0000ff;">false</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br></span><span style="color: #008080;">&nbsp;8</span>&nbsp;<span style="color: #000000;">{<br></span><span style="color: #008080;">&nbsp;9</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;T&nbsp;ValueType;<br></span><span style="color: #008080;">10</span>&nbsp;<span style="color: #000000;">};<br></span><span style="color: #008080;">11</span>&nbsp;<span style="color: #000000;">template&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">typename&nbsp;T,&nbsp;</span><span style="color: #0000ff;">bool</span><span style="color: #000000;">&nbsp;isPolymorphic</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br></span><span style="color: #008080;">12</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;NiftyContainer<br></span><span style="color: #008080;">13</span>&nbsp;<span style="color: #000000;">{<br></span><span style="color: #008080;">14</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;"><img src="http://www.cppblog.com/Images/dot.gif"></span><span style="color: #008000;"><br></span><span style="color: #008080;">15</span>&nbsp;<span style="color: #008000;"></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;NiftyContainerValueTraits</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">T,&nbsp;isPolymoriphic</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;Traits;<br></span><span style="color: #008080;">16</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;typename&nbsp;Traits::ValueType&nbsp;ValueType;<br></span><span style="color: #008080;">17</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;vector</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">ValueType</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;vec;<br></span><span style="color: #008080;">18</span>&nbsp;<span style="color: #000000;">};</span></div>
<br></span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;" lang="EN-US"><o:p></o:p></span></font></p>
<p class="MsoNormal" style="text-align: left;" align="left"><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">这种方法难用而且没有复用性，我们可以这样做：</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;" lang="EN-US"><o:p></o:p></span></font></p>
<p class="MsoNormal" style="text-align: left;" align="left"><font color="green" face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;; color: green;" lang="EN-US">
<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: #008080;">&nbsp;1</span>&nbsp;<span style="color: #000000;">template&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #0000ff;">bool</span><span style="color: #000000;">&nbsp;flag,&nbsp;typename&nbsp;T,&nbsp;typename&nbsp;U</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br></span><span style="color: #008080;">&nbsp;2</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;Select<br></span><span style="color: #008080;">&nbsp;3</span>&nbsp;<span style="color: #000000;">{<br></span><span style="color: #008080;">&nbsp;4</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;T&nbsp;Result;<br></span><span style="color: #008080;">&nbsp;5</span>&nbsp;<span style="color: #000000;">};<br></span><span style="color: #008080;">&nbsp;6</span>&nbsp;<span style="color: #000000;">template&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">typename&nbsp;T,&nbsp;typename&nbsp;U</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br></span><span style="color: #008080;">&nbsp;7</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;Select</span><span style="color: #000000;">&lt;</span><span style="color: #0000ff;">false</span><span style="color: #000000;">,&nbsp;T,&nbsp;U</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br></span><span style="color: #008080;">&nbsp;8</span>&nbsp;<span style="color: #000000;">{<br></span><span style="color: #008080;">&nbsp;9</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;U&nbsp;Result;<br></span><span style="color: #008080;">10</span>&nbsp;<span style="color: #000000;">};<br></span><span style="color: #008080;">11</span>&nbsp;<span style="color: #000000;">template&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">typename&nbsp;T,&nbsp;</span><span style="color: #0000ff;">bool</span><span style="color: #000000;">&nbsp;isPolymorphic</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br></span><span style="color: #008080;">12</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;NiftyContainer<br></span><span style="color: #008080;">13</span>&nbsp;<span style="color: #000000;">{<br></span><span style="color: #008080;">14</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;"><img src="http://www.cppblog.com/Images/dot.gif"></span><span style="color: #008000;"><br></span><span style="color: #008080;">15</span>&nbsp;<span style="color: #008000;"></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;Select</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">isPolymorphic,&nbsp;T</span><span style="color: #000000;">*</span><span style="color: #000000;">,&nbsp;T</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">::Result&nbsp;ValueType;<br></span><span style="color: #008080;">16</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;vector</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">ValueType</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;vec;<br></span><span style="color: #008080;">17</span>&nbsp;<span style="color: #000000;">};</span></div>
<br></span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;" lang="EN-US"><o:p></o:p></span></font></p>
</div><img src ="http://www.cppblog.com/cuigang/aggbug/39162.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cuigang/" target="_blank">cuigang</a> 2007-12-20 22:00 <a href="http://www.cppblog.com/cuigang/articles/39162.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>《C++设计新思维》读书笔记（十）</title><link>http://www.cppblog.com/cuigang/articles/38824.html</link><dc:creator>cuigang</dc:creator><author>cuigang</author><pubDate>Mon, 17 Dec 2007 14:16:00 GMT</pubDate><guid>http://www.cppblog.com/cuigang/articles/38824.html</guid><wfw:comment>http://www.cppblog.com/cuigang/comments/38824.html</wfw:comment><comments>http://www.cppblog.com/cuigang/articles/38824.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/cuigang/comments/commentRss/38824.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cuigang/services/trackbacks/38824.html</trackback:ping><description><![CDATA[<br>&nbsp;<br>2.5 型别对型别的映射（Type-to-Type Mapping）<br>&nbsp;<br>如前所述，不可以对template函数偏特化。如有下面模板函数：<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: #008080;">1</span>&nbsp;<span style="color: #000000;">template</span><span style="color: #000000;">&lt;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;T,&nbsp;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;U</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br></span><span style="color: #008080;">2</span>&nbsp;<span style="color: #000000;">T</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;Create(</span><span style="color: #0000ff;">const</span><span style="color: #000000;">&nbsp;U</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">&nbsp;arg)<br></span><span style="color: #008080;">3</span>&nbsp;<span style="color: #000000;">{<br></span><span style="color: #008080;">4</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;T(arg);<br></span><span style="color: #008080;">5</span>&nbsp;<span style="color: #000000;">}</span></div>
<br><br>用来构造一个对象。假设现在有一个widget对象的构造函数需要两个参数，第二个固定为-1。那么你没有办法如下偏特化，如果你写一个CreateWidget()来解决，你将不能在泛型程序中使用。<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: #008080;">1</span>&nbsp;<span style="color: #008000;">//</span><span style="color: #008000;">示意代码，请勿模仿</span><span style="color: #008000;"><br></span><span style="color: #008080;">2</span>&nbsp;<span style="color: #008000;"></span><span style="color: #000000;">template&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;U</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br></span><span style="color: #008080;">3</span>&nbsp;<span style="color: #000000;">widget</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;Create</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">widget,&nbsp;U</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">(</span><span style="color: #0000ff;">const</span><span style="color: #000000;">&nbsp;U</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">&nbsp;arg)<br></span><span style="color: #008080;">4</span>&nbsp;<span style="color: #000000;">{<br></span><span style="color: #008080;">5</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;widget(arg,&nbsp;</span><span style="color: #000000;">-</span><span style="color: #000000;">1</span><span style="color: #000000;">);<br></span><span style="color: #008080;">6</span>&nbsp;<span style="color: #000000;">}</span></div>
<br><br>我们可以通过重载机制来实现，比如传入一个型别为T的形参：<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: #008080;">&nbsp;1</span>&nbsp;<span style="color: #000000;">template&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;T,&nbsp;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;U</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br></span><span style="color: #008080;">&nbsp;2</span>&nbsp;<span style="color: #000000;">T</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;Create(cosnt&nbsp;U</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">&nbsp;arg,&nbsp;T&nbsp;</span><span style="color: #008000;">/*</span><span style="color: #008000;">&nbsp;dummy&nbsp;</span><span style="color: #008000;">*/</span><span style="color: #000000;">)<br></span><span style="color: #008080;">&nbsp;3</span>&nbsp;<span style="color: #000000;">{<br></span><span style="color: #008080;">&nbsp;4</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;T(arg);<br></span><span style="color: #008080;">&nbsp;5</span>&nbsp;<span style="color: #000000;">}<br></span><span style="color: #008080;">&nbsp;6</span>&nbsp;<span style="color: #000000;">template&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;U</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br></span><span style="color: #008080;">&nbsp;7</span>&nbsp;<span style="color: #000000;">widget</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;Create(</span><span style="color: #0000ff;">const</span><span style="color: #000000;">&nbsp;U</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">&nbsp;arg,&nbsp;widget&nbsp;</span><span style="color: #008000;">/*</span><span style="color: #008000;">&nbsp;dummy&nbsp;</span><span style="color: #008000;">*/</span><span style="color: #000000;">)<br></span><span style="color: #008080;">&nbsp;8</span>&nbsp;<span style="color: #000000;">{<br></span><span style="color: #008080;">&nbsp;9</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;widget(arg,&nbsp;</span><span style="color: #000000;">-</span><span style="color: #000000;">1</span><span style="color: #000000;">);<br></span><span style="color: #008080;">10</span>&nbsp;<span style="color: #000000;">}</span></div>
<br><br>但是由于形参的传入，我们构造了一个临时对象，造成额外开销。我们需要一个轻量级的ID。就是Type2Type：<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: #008080;">1</span>&nbsp;<span style="color: #000000;">template&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">typename&nbsp;T</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br></span><span style="color: #008080;">2</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;Type2Type<br></span><span style="color: #008080;">3</span>&nbsp;<span style="color: #000000;">{<br></span><span style="color: #008080;">4</span>&nbsp;<span style="color: #000000;">&nbsp;typedef&nbsp;T&nbsp;OriginalType;<br></span><span style="color: #008080;">5</span>&nbsp;<span style="color: #000000;">};<br></span><span style="color: #008080;">6</span>&nbsp;<span style="color: #000000;"></span></div>
<br>它没有任何数值，但它们各自不同型别。那么，现在可以这样写：<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: #008080;">&nbsp;1</span>&nbsp;<span style="color: #008000;">//</span><span style="color: #008000;">依靠重载和Type2Type</span><span style="color: #008000;"><br></span><span style="color: #008080;">&nbsp;2</span>&nbsp;<span style="color: #008000;"></span><span style="color: #000000;">template&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;T,&nbsp;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;U</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br></span><span style="color: #008080;">&nbsp;3</span>&nbsp;<span style="color: #000000;">T</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;Create(</span><span style="color: #0000ff;">const</span><span style="color: #000000;">&nbsp;U</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">&nbsp;arg,&nbsp;Type2Type</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">T</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">)<br></span><span style="color: #008080;">&nbsp;4</span>&nbsp;<span style="color: #000000;">{<br></span><span style="color: #008080;">&nbsp;5</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;T(arg);<br></span><span style="color: #008080;">&nbsp;6</span>&nbsp;<span style="color: #000000;">}<br></span><span style="color: #008080;">&nbsp;7</span>&nbsp;<span style="color: #000000;">template&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;U</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br></span><span style="color: #008080;">&nbsp;8</span>&nbsp;<span style="color: #000000;">widget</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;Create(</span><span style="color: #0000ff;">const</span><span style="color: #000000;">&nbsp;U</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">&nbsp;arg,&nbsp;Type2Type</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">widget</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">)<br></span><span style="color: #008080;">&nbsp;9</span>&nbsp;<span style="color: #000000;">{<br></span><span style="color: #008080;">10</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;widget(arg,&nbsp;</span><span style="color: #000000;">-</span><span style="color: #000000;">1</span><span style="color: #000000;">);<br></span><span style="color: #008080;">11</span>&nbsp;<span style="color: #000000;">}<br></span><span style="color: #008080;">12</span>&nbsp;<span style="color: #000000;"></span><span style="color: #008000;">//</span><span style="color: #008000;">cleint's&nbsp;code</span><span style="color: #008000;"><br></span><span style="color: #008080;">13</span>&nbsp;<span style="color: #008000;"></span><span style="color: #000000;">String</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;pStr&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;Create(</span><span style="color: #000000;">"</span><span style="color: #000000;">hello</span><span style="color: #000000;">"</span><span style="color: #000000;">,&nbsp;Type2Type</span><span style="color: #000000;">&lt;</span><span style="color: #0000ff;">string</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">());<br></span><span style="color: #008080;">14</span>&nbsp;<span style="color: #000000;">widget</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;pW&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;Create(</span><span style="color: #000000;">100</span><span style="color: #000000;">,&nbsp;Type2Type</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">widget</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">());</span></div>
<br><br>第二个参数只是用来选择适合的重载函数。<br>&nbsp;<br>&nbsp;<br> <img src ="http://www.cppblog.com/cuigang/aggbug/38824.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cuigang/" target="_blank">cuigang</a> 2007-12-17 22:16 <a href="http://www.cppblog.com/cuigang/articles/38824.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>《C++设计新思维》读书笔记（九）</title><link>http://www.cppblog.com/cuigang/articles/38823.html</link><dc:creator>cuigang</dc:creator><author>cuigang</author><pubDate>Mon, 17 Dec 2007 14:15:00 GMT</pubDate><guid>http://www.cppblog.com/cuigang/articles/38823.html</guid><wfw:comment>http://www.cppblog.com/cuigang/comments/38823.html</wfw:comment><comments>http://www.cppblog.com/cuigang/articles/38823.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/cuigang/comments/commentRss/38823.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cuigang/services/trackbacks/38823.html</trackback:ping><description><![CDATA[<br>&nbsp;<br>2.4 常整数映射为型别<br><br>以下模板：<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: #008080;">1</span>&nbsp;<span style="color: #000000;">template&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;v&nbsp;</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br></span><span style="color: #008080;">2</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;Int2Type{<br></span><span style="color: #008080;">3</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">enum</span><span style="color: #000000;">&nbsp;{&nbsp;value&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;v&nbsp;};<br></span><span style="color: #008080;">4</span>&nbsp;<span style="color: #000000;">}</span></div>
<br><br>Int2Type会根据引数所得的不同数值来产生不同型别。Int2Type&lt;0&gt; 和 Int2Type&lt;1&gt;是两种不同的类型。采用Int2Type可根据编译期计算出来的结果选用不同的函数。实际上你可以运用一个常数达到静态分派功能。<br><br>一般而言，符合下列两个条件可使用Int2Type：<br><br>a.有必要根据某个编译期常数调用一个或数个不同的函数。<br>b.有必要在编译期实施&#8220;分派&#8221;。<br><br>运行时分派可以使用if...else...或switch。但有时难以做到。举例如下：<br><br>假设一个容器NiftyContainer，<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: #008080;">1</span>&nbsp;<span style="color: #000000;">template&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;T</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;NiftyContainer{};</span></div>
<br><br>其内含指针，指向 T 的对象。为了复制容器中某个对象，你想调用copy构造函数（非多态）或虚函数Clone()（多态）。但你无法这样做：<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: #008080;">&nbsp;1</span>&nbsp;<span style="color: #000000;">template&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">&nbsp;typename&nbsp;T,&nbsp;</span><span style="color: #0000ff;">bool</span><span style="color: #000000;">&nbsp;isPolymorphic</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br></span><span style="color: #008080;">&nbsp;2</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;NiftyContainer{<br></span><span style="color: #008080;">&nbsp;3</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;DoSomething(){<br></span><span style="color: #008080;">&nbsp;4</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;T</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;pSomeObj&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;<img src="http://www.cppblog.com/Images/dot.gif">;<br></span><span style="color: #008080;">&nbsp;5</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(isPolymorphic){<br></span><span style="color: #008080;">&nbsp;6</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;T</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;pNewObj&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;pSomeObje</span><span style="color: #000000;">-&gt;</span><span style="color: #000000;">Clone();<br></span><span style="color: #008080;">&nbsp;7</span>&nbsp;<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;"><img src="http://www.cppblog.com/Images/dot.gif"></span><span style="color: #008000;"><br></span><span style="color: #008080;">&nbsp;8</span>&nbsp;<span style="color: #008000;"></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span><span style="color: #0000ff;">else</span><span style="color: #000000;">{<br></span><span style="color: #008080;">&nbsp;9</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;T</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;pNewObj&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;T(</span><span style="color: #000000;">*</span><span style="color: #000000;">pSomeObj);<br></span><span style="color: #008080;">10</span>&nbsp;<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;"><img src="http://www.cppblog.com/Images/dot.gif"></span><span style="color: #008000;"><br></span><span style="color: #008080;">11</span>&nbsp;<span style="color: #008000;"></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br></span><span style="color: #008080;">12</span>&nbsp;<span style="color: #000000;">};</span></div>
<br><br>你会发现编译不过，编译器会发现未定义的函数。而Int2Type提供了一个办法：<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: #008080;">&nbsp;1</span>&nbsp;<span style="color: #000000;">template&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">typename&nbsp;T,&nbsp;</span><span style="color: #0000ff;">bool</span><span style="color: #000000;">&nbsp;isPolymrphoic</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br></span><span style="color: #008080;">&nbsp;2</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;NiftyContainer{<br></span><span style="color: #008080;">&nbsp;3</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">private</span><span style="color: #000000;">:<br></span><span style="color: #008080;">&nbsp;4</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;DoSomething(T</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;pObj,&nbsp;Int2Type</span><span style="color: #000000;">&lt;</span><span style="color: #0000ff;">true</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">){<br></span><span style="color: #008080;">&nbsp;5</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;T</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;pNewObj&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;pSomeObje</span><span style="color: #000000;">-&gt;</span><span style="color: #000000;">Clone();<br></span><span style="color: #008080;">&nbsp;6</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;"><img src="http://www.cppblog.com/Images/dot.gif">&nbsp;&nbsp;</span><span style="color: #008000;"><br></span><span style="color: #008080;">&nbsp;7</span>&nbsp;<span style="color: #008000;"></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;}<br></span><span style="color: #008080;">&nbsp;8</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;DoSomething(T</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;pObj,&nbsp;Int2Type</span><span style="color: #000000;">&lt;</span><span style="color: #0000ff;">false</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">){<br></span><span style="color: #008080;">&nbsp;9</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;T</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;pNewObj&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;T(</span><span style="color: #000000;">*</span><span style="color: #000000;">pSomeObj);<br></span><span style="color: #008080;">10</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;"><img src="http://www.cppblog.com/Images/dot.gif"></span><span style="color: #008000;"><br></span><span style="color: #008080;">11</span>&nbsp;<span style="color: #008000;"></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;}<br></span><span style="color: #008080;">12</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">public</span><span style="color: #000000;">:<br></span><span style="color: #008080;">13</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;DoSomething(T</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;pObj){<br></span><span style="color: #008080;">14</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DoSomething(pObj,&nbsp;Int2Type</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">isPolymorphoic</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">());<br></span><span style="color: #008080;">15</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;}<br></span><span style="color: #008080;">16</span>&nbsp;<span style="color: #000000;">};</span></div>
<br><br>主要原因是编译器不会去编译一个未被用到的template函数。<br>&nbsp;<br> <img src ="http://www.cppblog.com/cuigang/aggbug/38823.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cuigang/" target="_blank">cuigang</a> 2007-12-17 22:15 <a href="http://www.cppblog.com/cuigang/articles/38823.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>《C++设计新思维》读书笔记（八）</title><link>http://www.cppblog.com/cuigang/articles/38822.html</link><dc:creator>cuigang</dc:creator><author>cuigang</author><pubDate>Mon, 17 Dec 2007 14:13:00 GMT</pubDate><guid>http://www.cppblog.com/cuigang/articles/38822.html</guid><wfw:comment>http://www.cppblog.com/cuigang/comments/38822.html</wfw:comment><comments>http://www.cppblog.com/cuigang/articles/38822.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/cuigang/comments/commentRss/38822.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cuigang/services/trackbacks/38822.html</trackback:ping><description><![CDATA[<br>&nbsp;<br>2.3 局部类<br><br>你可以在函数中定义class：<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: #008080;">1</span>&nbsp;<span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;Fun(){<br></span><span style="color: #008080;">2</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;Local{};&nbsp;<br></span><span style="color: #008080;">3</span>&nbsp;<span style="color: #000000;">}</span></div>
<br><br>不过有些限制，local class不能定义静态成员变量，也不能访问非静态局部变量。但它可以用于模板函数：<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: #008080;">&nbsp;1</span>&nbsp;<span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;Interface{<br></span><span style="color: #008080;">&nbsp;2</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">public</span><span style="color: #000000;">:<br></span><span style="color: #008080;">&nbsp;3</span>&nbsp;<span style="color: #000000;">&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;Fun()</span><span style="color: #000000;">=</span><span style="color: #000000;">0</span><span style="color: #000000;">;<br></span><span style="color: #008080;">&nbsp;4</span>&nbsp;<span style="color: #000000;">};<br></span><span style="color: #008080;">&nbsp;5</span>&nbsp;<span style="color: #000000;"><br></span><span style="color: #008080;">&nbsp;6</span>&nbsp;<span style="color: #000000;">template&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;T,&nbsp;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;P</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br></span><span style="color: #008080;">&nbsp;7</span>&nbsp;<span style="color: #000000;">Interface</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;MakeAdapter(</span><span style="color: #0000ff;">const</span><span style="color: #000000;">&nbsp;T</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">&nbsp;obj,&nbsp;</span><span style="color: #0000ff;">const</span><span style="color: #000000;">&nbsp;P</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">&nbsp;arg)<br></span><span style="color: #008080;">&nbsp;8</span>&nbsp;<span style="color: #000000;">{<br></span><span style="color: #008080;">&nbsp;9</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;Local&nbsp;:&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;Interface{<br></span><span style="color: #008080;">10</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">:<br></span><span style="color: #008080;">11</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Local(</span><span style="color: #0000ff;">const</span><span style="color: #000000;">&nbsp;T</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">&nbsp;obj,&nbsp;</span><span style="color: #0000ff;">const</span><span style="color: #000000;">&nbsp;P</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">&nbsp;arg)<br></span><span style="color: #008080;">12</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:&nbsp;obj_(obj),&nbsp;arg_(arg){};<br></span><span style="color: #008080;">13</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">virtual</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;Fun(){<br></span><span style="color: #008080;">14</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;obj_.Call(arg_);<br></span><span style="color: #008080;">15</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br></span><span style="color: #008080;">16</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">private</span><span style="color: #000000;">:<br></span><span style="color: #008080;">17</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;T&nbsp;obj_;<br></span><span style="color: #008080;">18</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P&nbsp;arg_;<br></span><span style="color: #008080;">19</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;};<br></span><span style="color: #008080;">20</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;Local(obj,&nbsp;arg);<br></span><span style="color: #008080;">21</span>&nbsp;<span style="color: #000000;">};</span></div>
<br><br>事实证明，任何local classes的方法都可以用&#8220;函数外的模板类&#8221;来完成，也就是说，并非得局部类不可。不过，局部类可以提高符号的地域性，如上例，Local不能在函数外被继承，类似Java的final。<br><br>11章将应用产生所谓&#8220;弹簧垫&#8221;函数（trampoline functions）。<br><br><br> <img src ="http://www.cppblog.com/cuigang/aggbug/38822.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cuigang/" target="_blank">cuigang</a> 2007-12-17 22:13 <a href="http://www.cppblog.com/cuigang/articles/38822.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>《C++设计新思维》读书笔记（七）</title><link>http://www.cppblog.com/cuigang/articles/38821.html</link><dc:creator>cuigang</dc:creator><author>cuigang</author><pubDate>Mon, 17 Dec 2007 14:12:00 GMT</pubDate><guid>http://www.cppblog.com/cuigang/articles/38821.html</guid><wfw:comment>http://www.cppblog.com/cuigang/comments/38821.html</wfw:comment><comments>http://www.cppblog.com/cuigang/articles/38821.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/cuigang/comments/commentRss/38821.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cuigang/services/trackbacks/38821.html</trackback:ping><description><![CDATA[<br>&nbsp;<br>2.2 模板偏特化<br><br>模板偏特化让你在template的所有可能实体中特化出一组子集。如：<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: #008080;">1</span>&nbsp;<span style="color: #000000;"><br></span><span style="color: #008080;">2</span>&nbsp;<span style="color: #000000;">template&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;Window,&nbsp;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;Controller</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br></span><span style="color: #008080;">3</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;Widget{};</span></div>
<br><br>你可以这样加以特化：<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: #008080;">1</span>&nbsp;<span style="color: #000000;">template&nbsp;</span><span style="color: #000000;">&lt;&gt;</span><span style="color: #000000;"><br></span><span style="color: #008080;">2</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;Widget</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">ModalDialog,&nbsp;MyController</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br></span><span style="color: #008080;">3</span>&nbsp;<span style="color: #000000;">{};</span></div>
<br><br>其中，ModalDialog 和 MyController 是另外定义的类。<br>有时候，你需要针对任意window并搭配一个特定的MyController来特化Widget，这时候就需要模板偏特化。<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: #008080;">1</span>&nbsp;<span style="color: #000000;">template&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;Window&nbsp;</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br></span><span style="color: #008080;">2</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;Widget&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">&nbsp;Window,&nbsp;MyController</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br></span><span style="color: #008080;">3</span>&nbsp;<span style="color: #000000;">{};</span></div>
<br><br>还可以拿任意Button来偏特化：<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: #008080;">1</span>&nbsp;<span style="color: #000000;">template&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;ButtonArg</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br></span><span style="color: #008080;">2</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;Widget</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">Button</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">ButtonArg</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">,&nbsp;MyController</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br></span><span style="color: #008080;">3</span>&nbsp;<span style="color: #000000;">{};</span></div>
<br><br>编译器会尝试找出最匹配的定义。但这样的机制不能用在函数身上，无论是成员函数还是非成员函数。<br> <img src ="http://www.cppblog.com/cuigang/aggbug/38821.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cuigang/" target="_blank">cuigang</a> 2007-12-17 22:12 <a href="http://www.cppblog.com/cuigang/articles/38821.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>《C++设计新思维》读书笔记（六）</title><link>http://www.cppblog.com/cuigang/articles/38820.html</link><dc:creator>cuigang</dc:creator><author>cuigang</author><pubDate>Mon, 17 Dec 2007 14:10:00 GMT</pubDate><guid>http://www.cppblog.com/cuigang/articles/38820.html</guid><wfw:comment>http://www.cppblog.com/cuigang/comments/38820.html</wfw:comment><comments>http://www.cppblog.com/cuigang/articles/38820.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/cuigang/comments/commentRss/38820.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cuigang/services/trackbacks/38820.html</trackback:ping><description><![CDATA[<br>&nbsp;<br>2.1 编译期断言<br><br>有时候，我们的断言其实在编译时就可以判断真假，于是有编译时断言。例如如此实现：<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: #008080;">1</span>&nbsp;<span style="color: #0000ff;">#define</span><span style="color: #000000;">&nbsp;STATIC_CHECK(expr)&nbsp;{char&nbsp;unnamed[(expr)?1:0];}</span></div>
<br><br>如果条件为假，编译器因大小为0的数组非法而报错。但出错信息显然没有实际意义，可以改进，使用模板：<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: #008080;">1</span>&nbsp;<span style="color: #000000;">template</span><span style="color: #000000;">&lt;</span><span style="color: #0000ff;">bool</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;CompileTimeError;<br></span><span style="color: #008080;">2</span>&nbsp;<span style="color: #000000;">template</span><span style="color: #000000;">&lt;&gt;</span><span style="color: #000000;">&nbsp;strcut&nbsp;CompileTimeError</span><span style="color: #000000;">&lt;</span><span style="color: #0000ff;">true</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">{};<br></span><span style="color: #008080;">3</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">#define</span><span style="color: #000000;">&nbsp;STATIC_CHECK(expr)&nbsp;(CompileTimeError&lt;(expr)!=0&gt;())</span></div>
<br><br>如果你试着具现化CompileTimeError&lt;false&gt;，编译器会提示&#8220;Undefined specialization CompileTimeError&lt;false&gt;&#8221;。<br>（进一步改进从略）<br> <img src ="http://www.cppblog.com/cuigang/aggbug/38820.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cuigang/" target="_blank">cuigang</a> 2007-12-17 22:10 <a href="http://www.cppblog.com/cuigang/articles/38820.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>《C++设计新思维》读书笔记（五）</title><link>http://www.cppblog.com/cuigang/articles/38818.html</link><dc:creator>cuigang</dc:creator><author>cuigang</author><pubDate>Mon, 17 Dec 2007 14:09:00 GMT</pubDate><guid>http://www.cppblog.com/cuigang/articles/38818.html</guid><wfw:comment>http://www.cppblog.com/cuigang/comments/38818.html</wfw:comment><comments>http://www.cppblog.com/cuigang/articles/38818.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/cuigang/comments/commentRss/38818.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cuigang/services/trackbacks/38818.html</trackback:ping><description><![CDATA[<br>&nbsp;<br>1.9 结合Policy Classes<br><br>当你将policies组合起来时，便是它们最有用的时候。举例，若我们整打算设计一个泛型的smart pointer。我们分析有两个policies：threading model（多线程模型）和check before dereference （提领前先检验），于是可以这样定义SmartPtr模板类。<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: #008080;">1</span>&nbsp;<span style="color: #000000;"><br></span><span style="color: #008080;">2</span>&nbsp;<span style="color: #000000;">template&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">&nbsp;Class&nbsp;T,<br></span><span style="color: #008080;">3</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;template&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;CheckingPolicy,<br></span><span style="color: #008080;">4</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;template&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;ThreadingModel<br></span><span style="color: #008080;">5</span>&nbsp;<span style="color: #000000;"></span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br></span><span style="color: #008080;">6</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;SmartPtr;</span></div>
<br><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: #008080;">1</span>&nbsp;<span style="color: #000000;"><br></span><span style="color: #008080;">2</span>&nbsp;<span style="color: #000000;">typedef&nbsp;SmartPtr</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">Widget,&nbsp;EnforceNoNull,&nbsp;Singlethreaded</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;SafeWigetPtr;</span></div>
<br><br>或者，<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: #008080;">1</span>&nbsp;<span style="color: #000000;">typedef&nbsp;SmartPtr</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">Widget,&nbsp;NoChecking,&nbsp;SingleThread</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;WidgetPTr;</span></div>
<br><br>一旦你设法把一个class分解成正交的policies，便可利用少量的代码涵盖大多数行为。<br><br>1.10 以Policy Classes 定制接口<br><br>templates的限制之一，你无法定制class的结构，只能定义其行为。而policy-based design支持结构方面的定制。<br><br>通过一个结构指针或者引用的聚合，或者依靠于继承。都可以。<br><br>1.11 Policies的兼容性<br><br>假设有两个SmartPtr：FastWidgetPtr是一个不需要检验的指针，SafeWidgetPtr则必须在提领（dereference）前检验。你能将一个FastWidgetPtr对象指派（赋值）给一个SafeWidgetPtr对象吗？<br><br>Policies之间的彼此转换，最好的方法是以Policy来控制SmartPtr对象之间的拷贝和初始化。如：<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: #008080;">1</span>&nbsp;<span style="color: #000000;">template</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">Class&nbsp;T,&nbsp;template</span><span style="color: #000000;">&lt;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;CheckingPolicy</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br></span><span style="color: #008080;">2</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;SmartPtr&nbsp;:&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;CheckingPolicy</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">T</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br></span><span style="color: #008080;">3</span>&nbsp;<span style="color: #000000;">{<br></span><span style="color: #008080;">4</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;"><img src="http://www.cppblog.com/Images/dot.gif"></span><span style="color: #008000;"><br></span><span style="color: #008080;">5</span>&nbsp;<span style="color: #008000;"></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;template</span><span style="color: #000000;">&lt;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;T1,&nbsp;template</span><span style="color: #000000;">&lt;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;CP1</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br></span><span style="color: #008080;">6</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SmartPtr(</span><span style="color: #0000ff;">const</span><span style="color: #000000;">&nbsp;SmartPtr</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">T1,&nbsp;CP1</span><span style="color: #000000;">&gt;&amp;</span><span style="color: #000000;">&nbsp;other</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br></span><span style="color: #008080;">7</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:&nbsp;pointee_(other.pointee_),&nbsp;CheckingPolicy</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">T</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">(other)<br></span><span style="color: #008080;">8</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{</span><span style="color: #008000;">//</span><span style="color: #008000;"><img src="http://www.cppblog.com/Images/dot.gif">}</span><span style="color: #008000;"><br></span><span style="color: #008080;">9</span>&nbsp;<span style="color: #008000;"></span><span style="color: #000000;">};</span></div>
<br><br>本节后续内容从略<br><br>1.12 将一个Class分解为一堆Policies<br>1.13 摘要<br>&nbsp;<br>&nbsp;<br> <img src ="http://www.cppblog.com/cuigang/aggbug/38818.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cuigang/" target="_blank">cuigang</a> 2007-12-17 22:09 <a href="http://www.cppblog.com/cuigang/articles/38818.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>《C++设计新思维》读书笔记（四）</title><link>http://www.cppblog.com/cuigang/articles/38814.html</link><dc:creator>cuigang</dc:creator><author>cuigang</author><pubDate>Mon, 17 Dec 2007 13:45:00 GMT</pubDate><guid>http://www.cppblog.com/cuigang/articles/38814.html</guid><wfw:comment>http://www.cppblog.com/cuigang/comments/38814.html</wfw:comment><comments>http://www.cppblog.com/cuigang/articles/38814.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/cuigang/comments/commentRss/38814.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cuigang/services/trackbacks/38814.html</trackback:ping><description><![CDATA[<br>&nbsp;<br>1.7 Policy Classes的析构函数<br><br>我们已知host class从policy class公有继承。那么将一个指向host class对象的policy class指针delete，将会产生不可预期的结果。解决方法有三：<br><br>1、将policy的析构函数声明为虚函数。但这样会妨碍policy的静态连接特性，也会影响执行效率。第一个虚函数的加入会使对象大小带来额外开销。<br><br>2、采用protected继承或private继承（派生类指针将不能转化为基类指针，cuigang）。但policy的函数则不能对外访问，失去用户扩充的特性（见1.6节）。<br><br>3、定义一个非虚的protected析构函数。（不能对基类指针delete，因为析构函数不可访问，cuigang）<br><br>方法3显然没有1、2的副作用。<br><br>1.8 通过不完全具现化而获得的选择性机能<br><br>更进一步。由于对于模板类中的成员函数，如果未曾用到，那么它就不会被编译器具现出来，有的编译器甚至不对其进行语法检查。如此便导致host class有机会指明并使用policy class的可选特性。如：<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: #008080;">&nbsp;1</span>&nbsp;<span style="color: #000000;">template&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">&nbsp;template&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;CreationPolicy&nbsp;</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br></span><span style="color: #008080;">&nbsp;2</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;WidgetManager&nbsp;:&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;CreationPolicy</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">Widget</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br></span><span style="color: #008080;">&nbsp;3</span>&nbsp;<span style="color: #000000;">{<br></span><span style="color: #008080;">&nbsp;4</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;"><img src="http://www.cppblog.com/Images/dot.gif"></span><span style="color: #008000;"><br></span><span style="color: #008080;">&nbsp;5</span>&nbsp;<span style="color: #008000;"></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;SwitchPrototype(Widget</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;pNewPrototype)<br></span><span style="color: #008080;">&nbsp;6</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span style="color: #008080;">&nbsp;7</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CreationPolicy</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">Widget</span><span style="color: #000000;">&gt;&amp;</span><span style="color: #000000;">&nbsp;myPolicy&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">*</span><span style="color: #0000ff;">this</span><span style="color: #000000;">;<br></span><span style="color: #008080;">&nbsp;8</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;delete&nbsp;myPolicy.GetPrototype();<br></span><span style="color: #008080;">&nbsp;9</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;myPolicy.SetPrototype(pNewPrototype);<br></span><span style="color: #008080;">10</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br></span><span style="color: #008080;">11</span>&nbsp;<span style="color: #000000;">}</span></div>
<br><br>那么<br><br>1、如果你采用的CreationPolicy支持GetPrototype()，那么使用WidgetManager::SwitchPrototype()没问题。<br><br>2、如果你采用的CreationPolicy不支持GetPrototype()，那么使用WidgetManager::SwitchPrototype()编译出错。<br><br>3、如果你采用的CreationPolicy不支持GetPrototype()，但是没有使用WidgetManager::SwitchPrototype()，那么没问题！！！<br><br>那么host class的作者就可以利用这种不完整具现化（incomplement instantiation），预定义一些可选的方法。<br>&nbsp;<br> <img src ="http://www.cppblog.com/cuigang/aggbug/38814.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cuigang/" target="_blank">cuigang</a> 2007-12-17 21:45 <a href="http://www.cppblog.com/cuigang/articles/38814.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>《C++设计新思维》读书笔记（三）</title><link>http://www.cppblog.com/cuigang/articles/38813.html</link><dc:creator>cuigang</dc:creator><author>cuigang</author><pubDate>Mon, 17 Dec 2007 13:44:00 GMT</pubDate><guid>http://www.cppblog.com/cuigang/articles/38813.html</guid><wfw:comment>http://www.cppblog.com/cuigang/comments/38813.html</wfw:comment><comments>http://www.cppblog.com/cuigang/articles/38813.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/cuigang/comments/commentRss/38813.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cuigang/services/trackbacks/38813.html</trackback:ping><description><![CDATA[<br>&nbsp;<br>1.5.1 运用Template Template参数实作Policy Classes<br><br>如前例，库代码host class如果已知policy class，那么可以这样描述：<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: #008080;">1</span>&nbsp;<span style="color: #000000;"><br></span><span style="color: #008080;">2</span>&nbsp;<span style="color: #000000;">//Library&nbsp;code<br></span><span style="color: #008080;">3</span>&nbsp;<span style="color: #000000;">template&nbsp;&lt;&nbsp;template&nbsp;&lt;&nbsp;class&nbsp;Created&nbsp;&gt;&nbsp;class&nbsp;CreationPolicy&nbsp;&gt;<br></span><span style="color: #008080;">4</span>&nbsp;<span style="color: #000000;">class&nbsp;WidgetManager&nbsp;:&nbsp;public&nbsp;CreationPolicy&lt;Widget&gt;{}</span><span style="color: #008000;">;</span></div>
<br><br>因为Created只是形式引数（formal argument），不可使用，可以省略如下：<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: #008080;">1</span>&nbsp;<span style="color: #000000;"><br></span><span style="color: #008080;">2</span>&nbsp;<span style="color: #000000;">template&nbsp;&lt;&nbsp;template&nbsp;&lt;&nbsp;class&nbsp;&gt;&nbsp;class&nbsp;CreationPolicy&nbsp;&gt;<br></span><span style="color: #008080;">3</span>&nbsp;<span style="color: #000000;">class&nbsp;WidgetManager&nbsp;:&nbsp;public&nbsp;CreateionPolicy&lt;Widget&gt;{}</span><span style="color: #008000;">;</span></div>
<br><br>客户代码为：<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: #008080;">1</span>&nbsp;<span style="color: #000000;">typedef&nbsp;WidgetManager&lt;OpNewCreator&gt;&nbsp;MyWidgetMgr</span><span style="color: #008000;">;</span></div>
<br><br>当WidgetManager希望在内部以相同的生成策略产生一个内部对象，那么这种template template形式不可或缺。<br><br>Policy的确能够带给WidgetManager非常大的弹性。第一，可以外部变更policies。第二，可以自定义policies。<br><br>WidgetManager的作者可以定义一些常用的policies，以&#8220;template 缺省引数&#8221;的方式提供：<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: #008080;">1</span>&nbsp;<span style="color: #000000;"><br></span><span style="color: #008080;">2</span>&nbsp;<span style="color: #000000;">template&nbsp;&lt;&nbsp;template&nbsp;&lt;&nbsp;class&nbsp;&gt;&nbsp;class&nbsp;CreationPolicy&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;OpNewCreator&nbsp;&gt;<br></span><span style="color: #008080;">3</span>&nbsp;<span style="color: #000000;">class&nbsp;WidgetManager&nbsp;<img src="http://www.cppblog.com/Images/dot.gif"><img src="http://www.cppblog.com/Images/dot.gif">.</span></div>
<br><br>1.5.2 运用Template 成员函数实作Policy Classes<br><br>我们可以把先前的Creator policy定义为一个非模板类，内部提供一个模板成员函数如下：<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: #008080;">&nbsp;1</span>&nbsp;<span style="color: #000000;"><br></span><span style="color: #008080;">&nbsp;2</span>&nbsp;<span style="color: #000000;">struct&nbsp;OpNewCreator<br></span><span style="color: #008080;">&nbsp;3</span>&nbsp;<span style="color: #000000;">{<br></span><span style="color: #008080;">&nbsp;4</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;template&nbsp;&lt;&nbsp;class&nbsp;T&nbsp;&gt;<br></span><span style="color: #008080;">&nbsp;5</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;static&nbsp;T*&nbsp;Create()<br></span><span style="color: #008080;">&nbsp;6</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span style="color: #008080;">&nbsp;7</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;new&nbsp;T</span><span style="color: #008000;">;<br></span><span style="color: #008080;">&nbsp;8</span>&nbsp;<span style="color: #008000;"></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br></span><span style="color: #008080;">&nbsp;9</span>&nbsp;<span style="color: #000000;">}<br></span><span style="color: #008080;">10</span>&nbsp;<span style="color: #000000;"></span></div>
<br>这种方式对旧式编译期有较佳兼容性。但难以讨论、定义、实作和运用。<br><br>1.6 更丰富的Policies<br><br>在前例的Creator policy中PrototypeCreateor除了提供Create()成员函数外，还提供了GetProtoType和SetProtoType两个函数，由于WidgetManager继承了policy class，所以WidgetManager具有此两个接口，虽然它自己并没有用。<br><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: #008080;">1</span>&nbsp;<span style="color: #000000;"><br></span><span style="color: #008080;">2</span>&nbsp;<span style="color: #000000;">typedef&nbsp;WidgetManager</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">PrototypeCreator</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;MyWidgetManager;<br></span><span style="color: #008080;">3</span>&nbsp;<span style="color: #000000;"></span><span style="color: #808080;">/////////<br></span><span style="color: #008080;">4</span>&nbsp;<span style="color: #808080;"></span><span style="color: #000000;">widget</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;pPrototype&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;<img src="http://www.cppblog.com/Images/dot.gif">;<br></span><span style="color: #008080;">5</span>&nbsp;<span style="color: #000000;">MyWidgetManager&nbsp;mgr;<br></span><span style="color: #008080;">6</span>&nbsp;<span style="color: #000000;">mgr.SetPrototype(pPrototype);</span></div>
<br><br>使用者如果需要扩充policies，可以在不影响host class原本功能的前提下，增加接口。&#8220;哪个policy被使用&#8221;由使用者决定而非程序库自身。policies给与使用者一种能力，在型别安全的前提下扩增host class的功能。<br><br>&nbsp;<br> <img src ="http://www.cppblog.com/cuigang/aggbug/38813.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cuigang/" target="_blank">cuigang</a> 2007-12-17 21:44 <a href="http://www.cppblog.com/cuigang/articles/38813.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>《C++设计新思维》读书笔记（二）</title><link>http://www.cppblog.com/cuigang/articles/38811.html</link><dc:creator>cuigang</dc:creator><author>cuigang</author><pubDate>Mon, 17 Dec 2007 13:41:00 GMT</pubDate><guid>http://www.cppblog.com/cuigang/articles/38811.html</guid><wfw:comment>http://www.cppblog.com/cuigang/comments/38811.html</wfw:comment><comments>http://www.cppblog.com/cuigang/articles/38811.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/cuigang/comments/commentRss/38811.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cuigang/services/trackbacks/38811.html</trackback:ping><description><![CDATA[《C++设计新思维》读书笔记（二）<br>&nbsp;<br>1.5 Policies和Policy Classes<br><br>举例，定义一个policy生成对象：Creator policy 提供一个Create函数，返回一个指向新生T类型对象的指针。<br><br>我们有三种做法：<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: #008080;">&nbsp;1</span>&nbsp;<span style="color: #000000;">template</span><span style="color: #000000;">&lt;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;T</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br></span><span style="color: #008080;">&nbsp;2</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;OpNewCreator{<br></span><span style="color: #008080;">&nbsp;3</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">static</span><span style="color: #000000;">&nbsp;T</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;Create(){<br></span><span style="color: #008080;">&nbsp;4</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;New&nbsp;T;<br></span><span style="color: #008080;">&nbsp;5</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br></span><span style="color: #008080;">&nbsp;6</span>&nbsp;<span style="color: #000000;">};<br></span><span style="color: #008080;">&nbsp;7</span>&nbsp;<span style="color: #000000;">template&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;T</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br></span><span style="color: #008080;">&nbsp;8</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;MallocCreator{<br></span><span style="color: #008080;">&nbsp;9</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">static</span><span style="color: #000000;">&nbsp;T</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;Create(){<br></span><span style="color: #008080;">10</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;buf&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;std::malloc(</span><span style="color: #0000ff;">sizeof</span><span style="color: #000000;">(T));<br></span><span style="color: #008080;">11</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">(</span><span style="color: #000000;">!</span><span style="color: #000000;">buf)&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><span style="color: #008080;">12</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">new</span><span style="color: #000000;">(buf)&nbsp;T;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">定位new表达式，见《C++&nbsp;primer》8.4.5，&nbsp;cuigang</span><span style="color: #008000;"><br></span><span style="color: #008080;">13</span>&nbsp;<span style="color: #008000;"></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br></span><span style="color: #008080;">14</span>&nbsp;<span style="color: #000000;">};<br></span><span style="color: #008080;">15</span>&nbsp;<span style="color: #000000;">template&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;T</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br></span><span style="color: #008080;">16</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;PrototypeCreator{<br></span><span style="color: #008080;">17</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PrototypeCreator(T</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;pObj&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">0</span><span style="color: #000000;">):pPrototype_(pObj){}<br></span><span style="color: #008080;">18</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;T</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;Create(){<br></span><span style="color: #008080;">19</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;pPrototype_</span><span style="color: #000000;">?</span><span style="color: #000000;">&nbsp;pPrototype_</span><span style="color: #000000;">-&gt;</span><span style="color: #000000;">Clone():</span><span style="color: #000000;">0</span><span style="color: #000000;">;<br></span><span style="color: #008080;">20</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br></span><span style="color: #008080;">21</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;T</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;GetPrototype(){&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;pPrototype_;}<br></span><span style="color: #008080;">22</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;SetPrototype(T</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;pObj){pPrototype_&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;pObj;}<br></span><span style="color: #008080;">23</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">private</span><span style="color: #000000;">:<br></span><span style="color: #008080;">24</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;T</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;pPrototype_;<br></span><span style="color: #008080;">25</span>&nbsp;<span style="color: #000000;">};<br></span><span style="color: #008080;">26</span>&nbsp;<span style="color: #000000;"></span></div>
<br>这些实作出来的policy称为policy classes，这个东西并不意图被单独使用，它们主要用于继承或被内含于其它classes。<br><br>一个类以复合或继承的方式使用先前定义的三个classes之一，例如<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: #008080;">1</span>&nbsp;<span style="color: #008000;">//</span><span style="color: #008000;">Library&nbsp;code</span><span style="color: #008000;"><br></span><span style="color: #008080;">2</span>&nbsp;<span style="color: #008000;"></span><span style="color: #000000;">template&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;CreationPolicy</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br></span><span style="color: #008080;">3</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;WidgetManager&nbsp;:&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;CreationPolicy{};</span></div>
<br><br>如果class采用一个或多个policies，我们称为hosts或host classes。<br><br>客户端如此实例化：<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: #008080;">1</span>&nbsp;<span style="color: #008000;">//</span><span style="color: #008000;">Application&nbsp;code</span><span style="color: #008000;"><br></span><span style="color: #008080;">2</span>&nbsp;<span style="color: #008000;"></span><span style="color: #000000;">typedef&nbsp;WidgetManager</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">&nbsp;OpNewCreator</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">widget</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;MywidgetMgr;</span></div>
<br><br>让我们分析整个来龙去脉。无论何时，当一个MywidgetMgr对象需要产生一个widget对象时，它便调用它的policy子对象OpNewCreator&lt;widget&gt;所提供的Createv()。选择&#8220;生成策略&#8221;（Creation policy）是WidgetManager使用者的权利。藉由这样的设计，可以让WidgetManager使用者自行装配他所需要的机能。<br><br>这便是Policy-based class的设计主旨。<br>&nbsp;<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: #008080;">1</span>&nbsp;<span style="color: #000000;">template&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;T</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br></span><span style="color: #008080;">2</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">void</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;buf&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;std::malloc(</span><span style="color: #0000ff;">sizeof</span><span style="color: #000000;">(T));<br></span><span style="color: #008080;">3</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">void</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;buf&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;&nbsp;(</span><span style="color: #0000ff;">void</span><span style="color: #000000;">*</span><span style="color: #000000;">)</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;T;</span></div>
<br>当T为基类，具有派生类时，两者申请的内存大小是不一致的，sizeof(T)不包括 virtual table 的大小。<br>——钟遥<br>&nbsp;<br>//////////////////////////////<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: #008080;">&nbsp;1</span>&nbsp;<span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">base</span><span style="color: #000000;">{<br></span><span style="color: #008080;">&nbsp;2</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;x;<br></span><span style="color: #008080;">&nbsp;3</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">base</span><span style="color: #000000;">(){<br></span><span style="color: #008080;">&nbsp;4</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;std::cout</span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">create&nbsp;a&nbsp;base.</span><span style="color: #000000;">"</span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;">std::endl;<br></span><span style="color: #008080;">&nbsp;5</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br></span><span style="color: #008080;">&nbsp;6</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">virtual</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;foo(){<br></span><span style="color: #008080;">&nbsp;7</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&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;">call&nbsp;base</span><span style="color: #000000;">"</span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;">std::endl;<br></span><span style="color: #008080;">&nbsp;8</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;};<br></span><span style="color: #008080;">&nbsp;9</span>&nbsp;<span style="color: #000000;">};<br></span><span style="color: #008080;">10</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;test&nbsp;:&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">base</span><span style="color: #000000;">{<br></span><span style="color: #008080;">11</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;y;<br></span><span style="color: #008080;">12</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;test(){<br></span><span style="color: #008080;">13</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;std::cout</span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">create&nbsp;a&nbsp;test.</span><span style="color: #000000;">"</span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;">std::endl;<br></span><span style="color: #008080;">14</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br></span><span style="color: #008080;">15</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">virtual</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;foo(){<br></span><span style="color: #008080;">16</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&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;">call&nbsp;test.</span><span style="color: #000000;">"</span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;">std::endl;<br></span><span style="color: #008080;">17</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br></span><span style="color: #008080;">18</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;foo2(){};<br></span><span style="color: #008080;">19</span>&nbsp;<span style="color: #000000;">};<br></span><span style="color: #008080;">20</span>&nbsp;<span style="color: #000000;"></span><span style="color: #808080;">////////////////////////</span><span style="color: #008000;">/</span><span style="color: #808080;"><br></span><span style="color: #008080;">21</span>&nbsp;<span style="color: #808080;"></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;a&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">sizeof</span><span style="color: #000000;">(test);<br></span><span style="color: #008080;">22</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;b&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">sizeof</span><span style="color: #000000;">(</span><span style="color: #0000ff;">base</span><span style="color: #000000;">);<br></span><span style="color: #008080;">23</span>&nbsp;<span style="color: #000000;">&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;">sizeof(test)=</span><span style="color: #000000;">"</span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;">&nbsp;a&nbsp;</span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">,&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;">"</span><span style="color: #000000;">sizeof(base)=</span><span style="color: #000000;">"</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;">&nbsp;b&nbsp;</span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;">&nbsp;endl;<br></span><span style="color: #008080;">24</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">base</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;pa&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">base</span><span style="color: #000000;">;<br></span><span style="color: #008080;">25</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">base</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;pb&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;test;<br></span><span style="color: #008080;">26</span>&nbsp;<span style="color: #000000;">&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;">---------</span><span style="color: #000000;">"</span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;">endl;<br></span><span style="color: #008080;">27</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">base</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;ppa&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;(</span><span style="color: #0000ff;">base</span><span style="color: #000000;">*</span><span style="color: #000000;">)malloc(</span><span style="color: #0000ff;">sizeof</span><span style="color: #000000;">(</span><span style="color: #0000ff;">base</span><span style="color: #000000;">));<br></span><span style="color: #008080;">28</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">base</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;ppb&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;(</span><span style="color: #0000ff;">base</span><span style="color: #000000;">*</span><span style="color: #000000;">)malloc(</span><span style="color: #0000ff;">sizeof</span><span style="color: #000000;">(test));<br></span><span style="color: #008080;">29</span>&nbsp;<span style="color: #000000;">&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;">---------</span><span style="color: #000000;">"</span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;">endl;<br></span><span style="color: #008080;">30</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">new</span><span style="color: #000000;">(ppa)&nbsp;</span><span style="color: #0000ff;">base</span><span style="color: #000000;">;<br></span><span style="color: #008080;">31</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">new</span><span style="color: #000000;">(ppb)&nbsp;test;<br></span><span style="color: #008080;">32</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pa</span><span style="color: #000000;">-&gt;</span><span style="color: #000000;">foo();<br></span><span style="color: #008080;">33</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pb</span><span style="color: #000000;">-&gt;</span><span style="color: #000000;">foo();<br></span><span style="color: #008080;">34</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ppa</span><span style="color: #000000;">-&gt;</span><span style="color: #000000;">foo();<br></span><span style="color: #008080;">35</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ppb</span><span style="color: #000000;">-&gt;</span><span style="color: #000000;">foo();</span></div>
<br><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: #008080;">&nbsp;1</span>&nbsp;<span style="color: #000000;">sizeof(test)</span><span style="color: #000000;">=</span><span style="color: #000000;">12</span><span style="color: #000000;">,</span><span style="color: #000000;">&nbsp;sizeof(base)</span><span style="color: #000000;">=</span><span style="color: #000000;">8</span><span style="color: #000000;"><br></span><span style="color: #008080;">&nbsp;2</span>&nbsp;<span style="color: #000000;">create&nbsp;a&nbsp;base.<br></span><span style="color: #008080;">&nbsp;3</span>&nbsp;<span style="color: #000000;">create&nbsp;a&nbsp;base.<br></span><span style="color: #008080;">&nbsp;4</span>&nbsp;<span style="color: #000000;">create&nbsp;a&nbsp;test.<br></span><span style="color: #008080;">&nbsp;5</span>&nbsp;<span style="color: #000000;">---------<br></span><span style="color: #008080;">&nbsp;6</span>&nbsp;<span style="color: #000000;">---------<br></span><span style="color: #008080;">&nbsp;7</span>&nbsp;<span style="color: #000000;">create&nbsp;a&nbsp;base.<br></span><span style="color: #008080;">&nbsp;8</span>&nbsp;<span style="color: #000000;">create&nbsp;a&nbsp;base.<br></span><span style="color: #008080;">&nbsp;9</span>&nbsp;<span style="color: #000000;">create&nbsp;a&nbsp;test.<br></span><span style="color: #008080;">10</span>&nbsp;<span style="color: #000000;">call&nbsp;base<br></span><span style="color: #008080;">11</span>&nbsp;<span style="color: #000000;">call&nbsp;test.<br></span><span style="color: #008080;">12</span>&nbsp;<span style="color: #000000;">call&nbsp;base<br></span><span style="color: #008080;">13</span>&nbsp;<span style="color: #000000;">call&nbsp;test.</span></div>
<br>&nbsp;<br>&nbsp;<br> <img src ="http://www.cppblog.com/cuigang/aggbug/38811.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cuigang/" target="_blank">cuigang</a> 2007-12-17 21:41 <a href="http://www.cppblog.com/cuigang/articles/38811.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>《C++设计新思维》读书笔记（一）</title><link>http://www.cppblog.com/cuigang/articles/38469.html</link><dc:creator>cuigang</dc:creator><author>cuigang</author><pubDate>Thu, 13 Dec 2007 16:16:00 GMT</pubDate><guid>http://www.cppblog.com/cuigang/articles/38469.html</guid><wfw:comment>http://www.cppblog.com/cuigang/comments/38469.html</wfw:comment><comments>http://www.cppblog.com/cuigang/articles/38469.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/cuigang/comments/commentRss/38469.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cuigang/services/trackbacks/38469.html</trackback:ping><description><![CDATA[<p><br>第一篇 技术</p>
<p>1 基于Policy的Class设计</p>
<p>1.1 软件设计的多样性</p>
<p>专业软件设计师与新手的最大不同在于，前者知道什么可以有效运作，什么不可以。任何设计结构上的问题，都有许多合适的解法，然而它们各有不同规格并且各有优缺点，对眼前的问题可能合适也可能不合适。白板上可接受的方案，不一定真有实用价值。</p>
<p>设计一个软件系统很困难，因为它不断要求你做抉择。而程序设计犹如人生，抉择是困难的。</p>
<p>1.2 全功能型接口的失败</p>
<p>庞大的classes不能视为成功，因为它们会导致沉重的学习负荷，并且有&#8220;非必要之大规模&#8221;倾向，使得代码远比手工制作还慢。</p>
<p>理想上，一个良好的设计应该在编译期强制表现出大部分constraints（约束条件、规范）。</p>
<p>1.3 多重继承是救世主？</p>
<p>藉由多重继承来组合多项功能，会产生如下问题：</p>
<p>a.关于技术（mechanics）。目前并没有一成不变即可套用的代码，可以在某种受控情况下将继承而来的classes组合（assemble）起来。大多数时候你得小心协调继承而来的classes的运转，让它们得到所需的行为。</p>
<p>b.关于型别信息（Type information）。Base classes并没有足够的型别信息来继续完成它们的工作。</p>
<p>c.关于状态处理（state manipulation）。base classes实作之各种行为必须操作相同的state（数据）。这意味着它们必须虚继承一个持有该state的base class。由于总是由user classes继承library classes（而非反向），这会使设计更加复杂而且变得没有弹性。</p>
<p>1.4 Templates带来曙光</p>
<p>templates是一种很适合&#8220;组合各种行为&#8221;的机制，主要因为它们是&#8220;依赖使用者提供的型别信息&#8221;并且&#8220;在编译期才产生&#8221;的代码。</p>
<p>和一般的class不同，class templates可以以不同的方式定制。（举例特化）</p>
<p>犹有进者，对于带有多个参数的class templates，你可以采用partial template specialization（偏特化）。（举例）</p>
<p>template的编译期特性以及&#8220;可互相组合&#8221;特性，使它在设计期非常引人注目。然而一旦你开始尝试实作这些设计，你会遭遇一些不是那么浅白的问题：</p>
<p>a.你无法特化结构，你只能特化其成员函数。</p>
<p>b.成员函数的特化并不能&#8220;依理扩张&#8221;。（这里指成员函数不具有偏特化行为，cuigang）</p>
<p>c.程序库撰写者不能够提供多笔缺省值。</p>
<p>多重继承和templates两者互补，如果我们将templates和多重继承组合起来，将会产生非常具弹性的设备（device），应该很适合用来产生程序库中的&#8220;设计元素&#8221;（design elements）。</p><img src ="http://www.cppblog.com/cuigang/aggbug/38469.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cuigang/" target="_blank">cuigang</a> 2007-12-14 00:16 <a href="http://www.cppblog.com/cuigang/articles/38469.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>