﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-万星星-随笔分类-模板</title><link>http://www.cppblog.com/wlwlxj/category/1324.html</link><description>&lt;div&gt;一个吃软饭的男人!!!!!我只想写程序####&lt;br&gt;师夷之技以制夷   吾尝终日而思矣,不如须臾之所学也&lt;br&gt;喝碗孟婆汤,踏过奈何桥,涅槃&lt;/div&gt;
I've been programming since I was 21. Started with C++, looked at Java, keen on Visual Basic and Visual C++, thinking about .NET and C#.^_^,very ridiculous.</description><language>zh-cn</language><lastBuildDate>Tue, 20 May 2008 09:27:26 GMT</lastBuildDate><pubDate>Tue, 20 May 2008 09:27:26 GMT</pubDate><ttl>60</ttl><item><title>动态多态与静态多态</title><link>http://www.cppblog.com/wlwlxj/archive/2006/09/25/12936.html</link><dc:creator>万连文</dc:creator><author>万连文</author><pubDate>Mon, 25 Sep 2006 02:38:00 GMT</pubDate><guid>http://www.cppblog.com/wlwlxj/archive/2006/09/25/12936.html</guid><wfw:comment>http://www.cppblog.com/wlwlxj/comments/12936.html</wfw:comment><comments>http://www.cppblog.com/wlwlxj/archive/2006/09/25/12936.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cppblog.com/wlwlxj/comments/commentRss/12936.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/wlwlxj/services/trackbacks/12936.html</trackback:ping><description><![CDATA[动态多态通过继承+虚函数实现，静态多态通过模版实现。<br />动态多态看上去很自然清晰，除此之外怕是没有别的好处。这也是为什么stl、boost为一群语法高手所亲眯的原因。说实话经常一看到模版都打冷战，要是模版参数一多，理清之间关系就得化很多时间。不过某些地方，使用模版来实现一些底层功能能达到意想不到的效果。<br />静态多态的好处：<br />1、可以多态成员变量(自创的说法哦^_^)<br />2、避免虚指针的内存损耗以及虚函数调用运行效率损耗<br />缺点：<br />1、因为编译时会加入类型的确定，代码尺寸会稍稍大一点<br />2、无法对多态对象统一处理，多态性稍有折扣<br /><br />MFC类很少使用模版，而WTL类大量使用模版。我在看WTL代码的时候，经常被里面的实现所迷惑，因为里面有很多设计采用动态多态和静态多态结合使用，这可能是一种不错的结合。下面我用一段代码演示这些特点，看上去很平常：<br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> Virtual &amp;&amp; inherit</span><span style="COLOR: #008000"><br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> Category1<br /><img id="Codehighlighter1_38_80_Open_Image" onclick="this.style.display='none'; Codehighlighter1_38_80_Open_Text.style.display='none'; Codehighlighter1_38_80_Closed_Image.style.display='inline'; Codehighlighter1_38_80_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_38_80_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_38_80_Closed_Text.style.display='none'; Codehighlighter1_38_80_Open_Image.style.display='inline'; Codehighlighter1_38_80_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align="top" /></span><span id="Codehighlighter1_38_80_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/images/dot.gif" /></span><span id="Codehighlighter1_38_80_Open_Text"><span style="COLOR: #000000">{<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" /></span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">:<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    </span><span style="COLOR: #0000ff">virtual</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> SayCatName() </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span></span><span style="COLOR: #000000">;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> Car1 : </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> Category1<br /><img id="Codehighlighter1_114_221_Open_Image" onclick="this.style.display='none'; Codehighlighter1_114_221_Open_Text.style.display='none'; Codehighlighter1_114_221_Closed_Image.style.display='inline'; Codehighlighter1_114_221_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_114_221_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_114_221_Closed_Text.style.display='none'; Codehighlighter1_114_221_Open_Image.style.display='inline'; Codehighlighter1_114_221_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align="top" /></span><span id="Codehighlighter1_114_221_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/images/dot.gif" /></span><span id="Codehighlighter1_114_221_Open_Text"><span style="COLOR: #000000">{<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" /></span><span style="COLOR: #0000ff">private</span><span style="COLOR: #000000">:<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    </span><span style="COLOR: #0000ff">static</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">string</span><span style="COLOR: #000000">    m_strName;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" /></span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">:<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    </span><span style="COLOR: #0000ff">virtual</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> SayCatName()<br /><img id="Codehighlighter1_187_219_Open_Image" onclick="this.style.display='none'; Codehighlighter1_187_219_Open_Text.style.display='none'; Codehighlighter1_187_219_Closed_Image.style.display='inline'; Codehighlighter1_187_219_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_187_219_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_187_219_Closed_Text.style.display='none'; Codehighlighter1_187_219_Open_Image.style.display='inline'; Codehighlighter1_187_219_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />    </span><span id="Codehighlighter1_187_219_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/images/dot.gif" /></span><span id="Codehighlighter1_187_219_Open_Text"><span style="COLOR: #000000">{<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />        cout </span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000"> m_strName </span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000"> endl;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />    }</span></span><span style="COLOR: #000000"><br /><img src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span></span><span style="COLOR: #000000">;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #0000ff">string</span><span style="COLOR: #000000"> Car1::m_strName </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">Car1</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> House1 : </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> Category1<br /><img id="Codehighlighter1_290_397_Open_Image" onclick="this.style.display='none'; Codehighlighter1_290_397_Open_Text.style.display='none'; Codehighlighter1_290_397_Closed_Image.style.display='inline'; Codehighlighter1_290_397_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_290_397_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_290_397_Closed_Text.style.display='none'; Codehighlighter1_290_397_Open_Image.style.display='inline'; Codehighlighter1_290_397_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align="top" /></span><span id="Codehighlighter1_290_397_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/images/dot.gif" /></span><span id="Codehighlighter1_290_397_Open_Text"><span style="COLOR: #000000">{<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" /></span><span style="COLOR: #0000ff">private</span><span style="COLOR: #000000">:<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    </span><span style="COLOR: #0000ff">static</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">string</span><span style="COLOR: #000000">    m_strName;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" /></span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">:<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    </span><span style="COLOR: #0000ff">virtual</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> SayCatName()<br /><img id="Codehighlighter1_363_395_Open_Image" onclick="this.style.display='none'; Codehighlighter1_363_395_Open_Text.style.display='none'; Codehighlighter1_363_395_Closed_Image.style.display='inline'; Codehighlighter1_363_395_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_363_395_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_363_395_Closed_Text.style.display='none'; Codehighlighter1_363_395_Open_Image.style.display='inline'; Codehighlighter1_363_395_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />    </span><span id="Codehighlighter1_363_395_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/images/dot.gif" /></span><span id="Codehighlighter1_363_395_Open_Text"><span style="COLOR: #000000">{<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />        cout </span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000"> m_strName </span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000"> endl;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />    }</span></span><span style="COLOR: #000000"><br /><img src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span></span><span style="COLOR: #000000">;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #0000ff">string</span><span style="COLOR: #000000"> House1::m_strName </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">Hourse1</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> !(Virtual &amp;&amp; inherit)<br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> Template</span><span style="COLOR: #008000"><br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #000000">template</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">typename T</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> Category2<br /><img id="Codehighlighter1_513_646_Open_Image" onclick="this.style.display='none'; Codehighlighter1_513_646_Open_Text.style.display='none'; Codehighlighter1_513_646_Closed_Image.style.display='inline'; Codehighlighter1_513_646_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_513_646_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_513_646_Closed_Text.style.display='none'; Codehighlighter1_513_646_Open_Image.style.display='inline'; Codehighlighter1_513_646_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align="top" /></span><span id="Codehighlighter1_513_646_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/images/dot.gif" /></span><span id="Codehighlighter1_513_646_Open_Text"><span style="COLOR: #000000">{<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" /></span><span style="COLOR: #0000ff">protected</span><span style="COLOR: #000000">:<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    </span><span style="COLOR: #0000ff">static</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">string</span><span style="COLOR: #000000"> m_strName;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" /></span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">:<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    </span><span style="COLOR: #0000ff">virtual</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> SayCatName()<br /><img id="Codehighlighter1_588_644_Open_Image" onclick="this.style.display='none'; Codehighlighter1_588_644_Open_Text.style.display='none'; Codehighlighter1_588_644_Closed_Image.style.display='inline'; Codehighlighter1_588_644_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_588_644_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_588_644_Closed_Text.style.display='none'; Codehighlighter1_588_644_Open_Image.style.display='inline'; Codehighlighter1_588_644_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />    </span><span id="Codehighlighter1_588_644_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/images/dot.gif" /></span><span id="Codehighlighter1_588_644_Open_Text"><span style="COLOR: #000000">{<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />        T</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">    pT    </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> static_cast</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">T</span><span style="COLOR: #000000">*&gt;</span><span style="COLOR: #000000">(</span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">);<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />        pT</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">SayCatName();<br /><img src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />    }</span></span><span style="COLOR: #000000"><br /><img src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span></span><span style="COLOR: #000000">;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> Car2 : </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> Category2</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">Car2</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br /><img id="Codehighlighter1_686_758_Open_Image" onclick="this.style.display='none'; Codehighlighter1_686_758_Open_Text.style.display='none'; Codehighlighter1_686_758_Closed_Image.style.display='inline'; Codehighlighter1_686_758_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_686_758_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_686_758_Closed_Text.style.display='none'; Codehighlighter1_686_758_Open_Image.style.display='inline'; Codehighlighter1_686_758_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align="top" /></span><span id="Codehighlighter1_686_758_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/images/dot.gif" /></span><span id="Codehighlighter1_686_758_Open_Text"><span style="COLOR: #000000">{<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" /></span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">:<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    </span><span style="COLOR: #0000ff">virtual</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> SayCatName()<br /><img id="Codehighlighter1_724_756_Open_Image" onclick="this.style.display='none'; Codehighlighter1_724_756_Open_Text.style.display='none'; Codehighlighter1_724_756_Closed_Image.style.display='inline'; Codehighlighter1_724_756_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_724_756_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_724_756_Closed_Text.style.display='none'; Codehighlighter1_724_756_Open_Image.style.display='inline'; Codehighlighter1_724_756_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />    </span><span id="Codehighlighter1_724_756_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/images/dot.gif" /></span><span id="Codehighlighter1_724_756_Open_Text"><span style="COLOR: #000000">{<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />        cout </span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000"> m_strName </span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000"> endl;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />    }</span></span><span style="COLOR: #000000"><br /><img src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span></span><span style="COLOR: #000000">;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #0000ff">string</span><span style="COLOR: #000000"> Car2::m_strName </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">Car2</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> House2 : </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> Category2</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">House2</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br /><img id="Codehighlighter1_835_907_Open_Image" onclick="this.style.display='none'; Codehighlighter1_835_907_Open_Text.style.display='none'; Codehighlighter1_835_907_Closed_Image.style.display='inline'; Codehighlighter1_835_907_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_835_907_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_835_907_Closed_Text.style.display='none'; Codehighlighter1_835_907_Open_Image.style.display='inline'; Codehighlighter1_835_907_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align="top" /></span><span id="Codehighlighter1_835_907_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/images/dot.gif" /></span><span id="Codehighlighter1_835_907_Open_Text"><span style="COLOR: #000000">{<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" /></span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">:<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    </span><span style="COLOR: #0000ff">virtual</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> SayCatName()<br /><img id="Codehighlighter1_873_905_Open_Image" onclick="this.style.display='none'; Codehighlighter1_873_905_Open_Text.style.display='none'; Codehighlighter1_873_905_Closed_Image.style.display='inline'; Codehighlighter1_873_905_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_873_905_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_873_905_Closed_Text.style.display='none'; Codehighlighter1_873_905_Open_Image.style.display='inline'; Codehighlighter1_873_905_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />    </span><span id="Codehighlighter1_873_905_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/images/dot.gif" /></span><span id="Codehighlighter1_873_905_Open_Text"><span style="COLOR: #000000">{<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />        cout </span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000"> m_strName </span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000"> endl;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />    }</span></span><span style="COLOR: #000000"><br /><img src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span></span><span style="COLOR: #000000">;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #0000ff">string</span><span style="COLOR: #000000"> House2::m_strName </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">House2</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> !(Template)<br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> Virtual &amp;&amp; inherit &amp;&amp; Template</span><span style="COLOR: #008000"><br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> CategoryBase<br /><img id="Codehighlighter1_1016_1058_Open_Image" onclick="this.style.display='none'; Codehighlighter1_1016_1058_Open_Text.style.display='none'; Codehighlighter1_1016_1058_Closed_Image.style.display='inline'; Codehighlighter1_1016_1058_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_1016_1058_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_1016_1058_Closed_Text.style.display='none'; Codehighlighter1_1016_1058_Open_Image.style.display='inline'; Codehighlighter1_1016_1058_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align="top" /></span><span id="Codehighlighter1_1016_1058_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/images/dot.gif" /></span><span id="Codehighlighter1_1016_1058_Open_Text"><span style="COLOR: #000000">{<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" /></span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">:<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    </span><span style="COLOR: #0000ff">virtual</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> SayCatName() </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span></span><span style="COLOR: #000000">;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />template</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">typename T, typename TBase</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">CategoryBase</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> CategoryImpl : </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> TBase<br /><img id="Codehighlighter1_1146_1185_Open_Image" onclick="this.style.display='none'; Codehighlighter1_1146_1185_Open_Text.style.display='none'; Codehighlighter1_1146_1185_Closed_Image.style.display='inline'; Codehighlighter1_1146_1185_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_1146_1185_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_1146_1185_Closed_Text.style.display='none'; Codehighlighter1_1146_1185_Open_Image.style.display='inline'; Codehighlighter1_1146_1185_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align="top" /></span><span id="Codehighlighter1_1146_1185_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/images/dot.gif" /></span><span id="Codehighlighter1_1146_1185_Open_Text"><span style="COLOR: #000000">{<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" /></span><span style="COLOR: #0000ff">protected</span><span style="COLOR: #000000">:<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    </span><span style="COLOR: #0000ff">static</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">string</span><span style="COLOR: #000000">    m_strName;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span></span><span style="COLOR: #000000">;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> Car3 : </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> CategoryImpl</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">Car3</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br /><img id="Codehighlighter1_1228_1300_Open_Image" onclick="this.style.display='none'; Codehighlighter1_1228_1300_Open_Text.style.display='none'; Codehighlighter1_1228_1300_Closed_Image.style.display='inline'; Codehighlighter1_1228_1300_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_1228_1300_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_1228_1300_Closed_Text.style.display='none'; Codehighlighter1_1228_1300_Open_Image.style.display='inline'; Codehighlighter1_1228_1300_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align="top" /></span><span id="Codehighlighter1_1228_1300_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/images/dot.gif" /></span><span id="Codehighlighter1_1228_1300_Open_Text"><span style="COLOR: #000000">{<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" /></span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">:<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    </span><span style="COLOR: #0000ff">virtual</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> SayCatName()<br /><img id="Codehighlighter1_1266_1298_Open_Image" onclick="this.style.display='none'; Codehighlighter1_1266_1298_Open_Text.style.display='none'; Codehighlighter1_1266_1298_Closed_Image.style.display='inline'; Codehighlighter1_1266_1298_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_1266_1298_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_1266_1298_Closed_Text.style.display='none'; Codehighlighter1_1266_1298_Open_Image.style.display='inline'; Codehighlighter1_1266_1298_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />    </span><span id="Codehighlighter1_1266_1298_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/images/dot.gif" /></span><span id="Codehighlighter1_1266_1298_Open_Text"><span style="COLOR: #000000">{<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />        cout </span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000"> m_strName </span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000"> endl;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />    }</span></span><span style="COLOR: #000000"><br /><img src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span></span><span style="COLOR: #000000">;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #0000ff">string</span><span style="COLOR: #000000"> Car3::m_strName </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">Car3</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> House3 : </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> CategoryImpl</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">House3</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br /><img id="Codehighlighter1_1380_1452_Open_Image" onclick="this.style.display='none'; Codehighlighter1_1380_1452_Open_Text.style.display='none'; Codehighlighter1_1380_1452_Closed_Image.style.display='inline'; Codehighlighter1_1380_1452_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_1380_1452_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_1380_1452_Closed_Text.style.display='none'; Codehighlighter1_1380_1452_Open_Image.style.display='inline'; Codehighlighter1_1380_1452_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align="top" /></span><span id="Codehighlighter1_1380_1452_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/images/dot.gif" /></span><span id="Codehighlighter1_1380_1452_Open_Text"><span style="COLOR: #000000">{<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" /></span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">:<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    </span><span style="COLOR: #0000ff">virtual</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> SayCatName()<br /><img id="Codehighlighter1_1418_1450_Open_Image" onclick="this.style.display='none'; Codehighlighter1_1418_1450_Open_Text.style.display='none'; Codehighlighter1_1418_1450_Closed_Image.style.display='inline'; Codehighlighter1_1418_1450_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_1418_1450_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_1418_1450_Closed_Text.style.display='none'; Codehighlighter1_1418_1450_Open_Image.style.display='inline'; Codehighlighter1_1418_1450_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />    </span><span id="Codehighlighter1_1418_1450_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/images/dot.gif" /></span><span id="Codehighlighter1_1418_1450_Open_Text"><span style="COLOR: #000000">{<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />        cout </span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000"> m_strName </span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000"> endl;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />    }</span></span><span style="COLOR: #000000"><br /><img src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span></span><span style="COLOR: #000000">;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #0000ff">string</span><span style="COLOR: #000000"> House3::m_strName </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">House3</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> !(Virtual &amp;&amp; inherit &amp;&amp; Template)</span><span style="COLOR: #008000"><br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #000000"><br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> _tmain(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> argc, _TCHAR</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000"> argv[])<br /><img id="Codehighlighter1_1567_2332_Open_Image" onclick="this.style.display='none'; Codehighlighter1_1567_2332_Open_Text.style.display='none'; Codehighlighter1_1567_2332_Closed_Image.style.display='inline'; Codehighlighter1_1567_2332_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_1567_2332_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_1567_2332_Closed_Text.style.display='none'; Codehighlighter1_1567_2332_Open_Image.style.display='inline'; Codehighlighter1_1567_2332_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align="top" /></span><span id="Codehighlighter1_1567_2332_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/images/dot.gif" /></span><span id="Codehighlighter1_1567_2332_Open_Text"><span style="COLOR: #000000">{<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> test Virtual &amp;&amp; inherit</span><span style="COLOR: #008000"><br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" /></span><span style="COLOR: #000000">    Category1</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">    pCatInstance    </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000"> Car1();<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    pCatInstance</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">SayCatName();<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    delete pCatInstance;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    pCatInstance </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> NULL;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    pCatInstance </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000"> House1();<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    pCatInstance</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">SayCatName();<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    delete pCatInstance;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    pCatInstance </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> NULL;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> !(test Virtual &amp;&amp; inherit)<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" /><br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> test Template</span><span style="COLOR: #008000"><br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" /></span><span style="COLOR: #000000">    Category2</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">Car2</span><span style="COLOR: #000000">&gt;*</span><span style="COLOR: #000000">    pCar2    </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000"> Car2();<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    pCar2</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">SayCatName();<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    delete pCar2;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    pCar2 </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> NULL;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    Category2</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">House2</span><span style="COLOR: #000000">&gt;*</span><span style="COLOR: #000000">    pHouse2    </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000"> House2();<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    pHouse2</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">SayCatName();<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    delete pHouse2;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    pHouse2 </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> NULL;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> !(test Template)<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" /><br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> test Virtual &amp;&amp; inherit &amp;&amp; Template</span><span style="COLOR: #008000"><br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" /></span><span style="COLOR: #000000">    CategoryBase</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">    pBase    </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000"> Car3();<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    pBase</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">SayCatName();<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    delete pBase;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    pBase </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> NULL;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    pBase </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000"> House3();<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    pBase</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">SayCatName();<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    delete pBase;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    pBase </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> NULL;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> !(test Virtual &amp;&amp; inherit &amp;&amp; Template)</span><span style="COLOR: #008000"><br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" /></span><span style="COLOR: #000000">    </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span></span></div>里面体现了很多特性，有些例如静态函数的巧妙使用没有演示。<br /><br />例子完全是本人臆想出来的，没有实际意义，仅从语法上去考虑。<img src ="http://www.cppblog.com/wlwlxj/aggbug/12936.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/wlwlxj/" target="_blank">万连文</a> 2006-09-25 10:38 <a href="http://www.cppblog.com/wlwlxj/archive/2006/09/25/12936.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>std::string一个极其隐晦得问题</title><link>http://www.cppblog.com/wlwlxj/archive/2006/04/18/5819.html</link><dc:creator>万连文</dc:creator><author>万连文</author><pubDate>Tue, 18 Apr 2006 08:23:00 GMT</pubDate><guid>http://www.cppblog.com/wlwlxj/archive/2006/04/18/5819.html</guid><wfw:comment>http://www.cppblog.com/wlwlxj/comments/5819.html</wfw:comment><comments>http://www.cppblog.com/wlwlxj/archive/2006/04/18/5819.html#Feedback</comments><slash:comments>7</slash:comments><wfw:commentRss>http://www.cppblog.com/wlwlxj/comments/commentRss/5819.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/wlwlxj/services/trackbacks/5819.html</trackback:ping><description><![CDATA[
		<p>昨天做一个dll，代码很快写完了，然而使用得时候总是遇到string内部指针删除错误，郁闷了一天，今天没去公司，好好研究了一下。<br />首先看下下面这段代码，声明两个string对象：<br /></p>
		<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee">
				<img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />
				<span style="COLOR: #000000">std::</span>
				<span style="COLOR: #0000ff">string</span>
				<span style="COLOR: #000000">  s1 </span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000"> </span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">wlwlxj</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />std::</span>
				<span style="COLOR: #0000ff">string</span>
				<span style="COLOR: #000000">  s2 </span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000"> </span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">lxjwlwww</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">;</span>
		</div>
		<p>调试状态下可以看到内部指针：<br />s1=0x00364ff9<br />s2=0x00365061<br />然后执行</p>
		<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee">
				<img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />
				<span style="COLOR: #000000">s2 </span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000"> s1;</span>
		</div>
		<p>按下f11，进入xstring源文件：</p>
		<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee">
				<img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />
				<span style="COLOR: #000000">_Myt</span>
				<span style="COLOR: #000000">&amp;</span>
				<span style="COLOR: #000000"> </span>
				<span style="COLOR: #0000ff">operator</span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000">(</span>
				<span style="COLOR: #0000ff">const</span>
				<span style="COLOR: #000000"> _Myt</span>
				<span style="COLOR: #000000">&amp;</span>
				<span style="COLOR: #000000"> _X)         // 赋值操作符<br /><img id="Codehighlighter1_34_56_Open_Image" onclick="this.style.display='none'; Codehighlighter1_34_56_Open_Text.style.display='none'; Codehighlighter1_34_56_Closed_Image.style.display='inline'; Codehighlighter1_34_56_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_34_56_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_34_56_Closed_Text.style.display='none'; Codehighlighter1_34_56_Open_Image.style.display='inline'; Codehighlighter1_34_56_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align="top" />  </span>
				<span id="Codehighlighter1_34_56_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">
						<img src="http://www.cppblog.com/images/dot.gif" />
				</span>
				<span id="Codehighlighter1_34_56_Open_Text">
						<span style="COLOR: #000000">{</span>
						<span style="COLOR: #0000ff">return</span>
						<span style="COLOR: #000000"> (assign(_X)); }                     // 调用assign函数</span>
				</span>
		</div>
		<p>继续进入assign(_X)函数：</p>
		<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee">
				<img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />
				<span style="COLOR: #000000">_Myt</span>
				<span style="COLOR: #000000">&amp;</span>
				<span style="COLOR: #000000"> assign(</span>
				<span style="COLOR: #0000ff">const</span>
				<span style="COLOR: #000000"> _Myt</span>
				<span style="COLOR: #000000">&amp;</span>
				<span style="COLOR: #000000"> _X)<br /><img id="Codehighlighter1_31_62_Open_Image" onclick="this.style.display='none'; Codehighlighter1_31_62_Open_Text.style.display='none'; Codehighlighter1_31_62_Closed_Image.style.display='inline'; Codehighlighter1_31_62_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_31_62_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_31_62_Closed_Text.style.display='none'; Codehighlighter1_31_62_Open_Image.style.display='inline'; Codehighlighter1_31_62_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align="top" />        </span>
				<span id="Codehighlighter1_31_62_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">
						<img src="http://www.cppblog.com/images/dot.gif" />
				</span>
				<span id="Codehighlighter1_31_62_Open_Text">
						<span style="COLOR: #000000">{</span>
						<span style="COLOR: #0000ff">return</span>
						<span style="COLOR: #000000"> (assign(_X, </span>
						<span style="COLOR: #000000">0</span>
						<span style="COLOR: #000000">, npos)); }   // 调用assign函数</span>
				</span>
		</div>继续进入assign函数，好戏都在这里面：<br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /><span style="COLOR: #000000">_Myt</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000"> assign(</span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000"> _Myt</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000"> _X, size_type _P, size_type _M)<br /><img id="Codehighlighter1_59_543_Open_Image" onclick="this.style.display='none'; Codehighlighter1_59_543_Open_Text.style.display='none'; Codehighlighter1_59_543_Closed_Image.style.display='inline'; Codehighlighter1_59_543_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_59_543_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_59_543_Closed_Text.style.display='none'; Codehighlighter1_59_543_Open_Image.style.display='inline'; Codehighlighter1_59_543_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align="top" />        </span><span id="Codehighlighter1_59_543_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/images/dot.gif" /></span><span id="Codehighlighter1_59_543_Open_Text"><span style="COLOR: #000000">{</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> (_X.size() </span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000"> _P)<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />            _Xran();<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />        size_type _N </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> _X.size() </span><span style="COLOR: #000000">-</span><span style="COLOR: #000000"> _P;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />        </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> (_M </span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000"> _N)<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />            _N </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> _M;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />        </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> (</span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">==</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">_X)<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />            erase((size_type)(_P </span><span style="COLOR: #000000">+</span><span style="COLOR: #000000"> _N)), erase(</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">, _P);<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />        </span><span style="COLOR: #0000ff">else</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> (</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000"> _N </span><span style="COLOR: #000000">&amp;&amp;</span><span style="COLOR: #000000"> _N </span><span style="COLOR: #000000">==</span><span style="COLOR: #000000"> _X.size()                        // 这个分支意思就是如果拷贝源有内容且就是就是源本身，并且<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />            </span><span style="COLOR: #000000">&amp;&amp;</span><span style="COLOR: #000000"> _Refcnt(_X.c_str()) </span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000"> _FROZEN </span><span style="COLOR: #000000">-</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">1          // 源字符串引用次数少于255-1次（可见引用次数最多255次），</span><span style="COLOR: #000000"><br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />            </span><span style="COLOR: #000000">&amp;&amp;</span><span style="COLOR: #000000"> allocator </span><span style="COLOR: #000000">==</span><span style="COLOR: #000000"> _X.allocator)                           //且源字符和目的字符分配器一致<br /><img id="Codehighlighter1_330_438_Open_Image" onclick="this.style.display='none'; Codehighlighter1_330_438_Open_Text.style.display='none'; Codehighlighter1_330_438_Closed_Image.style.display='inline'; Codehighlighter1_330_438_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_330_438_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_330_438_Closed_Text.style.display='none'; Codehighlighter1_330_438_Open_Image.style.display='inline'; Codehighlighter1_330_438_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />            </span><span id="Codehighlighter1_330_438_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/images/dot.gif" /></span><span id="Codehighlighter1_330_438_Open_Text"><span style="COLOR: #000000">{_Tidy(</span><span style="COLOR: #0000ff">true</span><span style="COLOR: #000000">);                                             // 删除本身<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />            _Ptr </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> (_E </span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">)_X.c_str();                                    // 复制内容到目的串<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />            _Len </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> _X.size();<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />            _Res </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> _X.capacity();<br /><img src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />            </span><span style="COLOR: #000000">++</span><span style="COLOR: #000000">_Refcnt(_Ptr); }                                             // 增加一次引用</span></span><span style="COLOR: #000000"><br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />        </span><span style="COLOR: #0000ff">else</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> (_Grow(_N, </span><span style="COLOR: #0000ff">true</span><span style="COLOR: #000000">))<br /><img id="Codehighlighter1_471_523_Open_Image" onclick="this.style.display='none'; Codehighlighter1_471_523_Open_Text.style.display='none'; Codehighlighter1_471_523_Closed_Image.style.display='inline'; Codehighlighter1_471_523_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_471_523_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_471_523_Closed_Text.style.display='none'; Codehighlighter1_471_523_Open_Image.style.display='inline'; Codehighlighter1_471_523_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />            </span><span id="Codehighlighter1_471_523_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/images/dot.gif" /></span><span id="Codehighlighter1_471_523_Open_Text"><span style="COLOR: #000000">{_Tr::copy(_Ptr, </span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">_X.c_str()[_P], _N);<br /><img src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />            _Eos(_N); }</span></span><span style="COLOR: #000000"><br /><img src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />        </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> (</span><span style="COLOR: #000000">*</span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">); }</span></span></div><p>这样结果就是调用=号以后，s2地址和s1地址一样，都是0x00364ff9。<br /><br />假如我们动态库有这样一个类class DLL接口：</p><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /><span style="COLOR: #000000">SetString(std::</span><span style="COLOR: #0000ff">string</span><span style="COLOR: #000000"> str)<br /><img id="Codehighlighter1_27_42_Open_Image" onclick="this.style.display='none'; Codehighlighter1_27_42_Open_Text.style.display='none'; Codehighlighter1_27_42_Closed_Image.style.display='inline'; Codehighlighter1_27_42_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_27_42_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_27_42_Closed_Text.style.display='none'; Codehighlighter1_27_42_Open_Image.style.display='inline'; Codehighlighter1_27_42_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align="top" /></span><span id="Codehighlighter1_27_42_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/images/dot.gif" /></span><span id="Codehighlighter1_27_42_Open_Text"><span style="COLOR: #000000">{<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />m_str </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> str;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span></span><span style="COLOR: #000000"><br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /></span></div><p>在客户调用时候：</p><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /><span style="COLOR: #000000">std::</span><span style="COLOR: #0000ff">string</span><span style="COLOR: #000000"> str </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">wlwlxj</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />DLL d;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />d.SetString(str); </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> 此时没有深拷贝，而是引用了str内部指针地址</span></div>在调用结束的时候，dll内部删除成员变量的时候，会判断m_str内部指针合法性，由于实际分配是在调用端，在dll内部自然检查指针非法。<br /><br />解决方法就是避免std::string引用计数，接口处修改为SetString(const char*)，这样在dll内部分配内存，内部释放，就不会有问题。<img src ="http://www.cppblog.com/wlwlxj/aggbug/5819.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/wlwlxj/" target="_blank">万连文</a> 2006-04-18 16:23 <a href="http://www.cppblog.com/wlwlxj/archive/2006/04/18/5819.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C++ Template: The Complete Guide 学习－9 模板中的命名</title><link>http://www.cppblog.com/wlwlxj/archive/2006/04/08/5169.html</link><dc:creator>万连文</dc:creator><author>万连文</author><pubDate>Sat, 08 Apr 2006 03:38:00 GMT</pubDate><guid>http://www.cppblog.com/wlwlxj/archive/2006/04/08/5169.html</guid><wfw:comment>http://www.cppblog.com/wlwlxj/comments/5169.html</wfw:comment><comments>http://www.cppblog.com/wlwlxj/archive/2006/04/08/5169.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/wlwlxj/comments/commentRss/5169.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/wlwlxj/services/trackbacks/5169.html</trackback:ping><description><![CDATA[
		<strong>第9章 模板中的名字</strong>
		<br />名字在大多数编程语言中都是最基本的概念，程序员用它来引用先前创建的对象。当C++编译器遇到一个名字，它要去查找并识别哪个对象被引用。从实现者角度来看，C++在一种强类型语言。考虑表达式X*Y：如果X和Y都是变量名，那么是乘法表达式；如果X是类型名，这条语句把Y声明为X类型的一个指针。<br /><br />这个例子表明C++（和C一样）是上下文敏感的语言：如果没有上下文，一条程序指令很难被编译器理解。这与模板有什么关系呢？嗯，模板必须处理更多的上下文：(1)模板内部上下文；(2)模板实例化时的上下文；(3)模板实例化时模板参数的上下文。在C++中必须小心处理名字，对此你不应该感到惊讶。<br /><br /><strong>9.1 名字分类学</strong><br />事实上C++的名字分类有很多种。为了便于记忆，我们提供了表格9.1和表格9.2描述了这些分类。幸运的是你只用熟悉下面2种主要的命名概念，就可以很好的理解C++模板中遇到的问题：<br /><br />1、限定名：名字在作用域中被显式指示作用域解析运算符(<font face="Courier New">::</font>)或者成员访问运算符(.或者<font face="Courier New">-&gt;</font>)。例如：this<font face="Courier New">-&gt;</font>count是限定名，而count不是（尽管count有可能是某个类的成员）。<br />2、依赖名：名字依赖于模板参数。例如：<font face="Courier New">std::vector&lt;T&gt;::iterator，如果T是模板参数，iterator就是依赖名；如果T是已知类型（比如int），iterator就是非依赖名。<br /><br /></font><table cellspacing="0" cellpadding="1" width="100%" border="1"><caption><h5 class="docTableTitle"><font face="Courier New">表格 9.1. 名字分类学 (第一部分)</font></h5></caption><colgroup span="2"><font face="Courier New"></font></colgroup><tbody><tr><th class="docTableHeader" valign="top" width="80"><p class="docText"><span class="docEmphStrong">分类</span></p></th><th class="docTableHeader" valign="top"><p class="docText"><span class="docEmphStrong">注释</span></p></th></tr><tr><td class="docTableCell" valign="top"><p class="docText">标识符</p></td><td class="docTableCell" valign="top"><p class="docText">由字符、下划线(_)和数字组成的名字，不能以数字开头。有一些标识符是保留的，你不能在自己程序中引入它们(一种避免引入的笨方法是以_或者__作为前缀)。字符的概念很广泛，包括对非字母语言编码的特殊字符。</p></td></tr><tr><td class="docTableCell" valign="top"><p class="docText">操作符类</p></td><td class="docTableCell" valign="top"><p class="docText">关键字operator 后面跟着一个符号。例如operator new和operator []。很多操作符都是多义的，例如operator &amp;可以是按位与运算，也可以是取地址运算。</p></td></tr><tr><td class="docTableCell" valign="top"><p class="docText">转换类</p></td><td class="docTableCell" valign="top"><p class="docText">指示用户定义的隐式类型转换。例如operator int&amp;，我们可以把它转换成int类型的位与操作</p></td></tr><tr><td class="docTableCell" valign="top"><p class="docText">模板类</p></td><td class="docTableCell" valign="top"><p class="docText">template后面跟着&lt;&gt;，里面是模板参数。例如List&lt;T, int, 0&gt;(严格讲，C++标准只允许简单的标识符为模板名，或许有争议说操作符类也是允许的；例如：operator+&lt;X&lt;int&gt; &gt;)。</p></td></tr><tr><td class="docTableCell" valign="top"><p class="docText">非限定类</p></td><td class="docTableCell" valign="top"><p class="docText">更一般的标识符。可以是上面几类(标识符、操作符类、转换类或模板类)或者是析构名(例如，像~Data 或 <font face="Times New Roman"><tt>~List&lt;T, T, N&gt;之类的</tt>符号)。</font></p></td></tr><tr><td class="docTableCell" valign="top"><p class="docText">限定类</p></td><td class="docTableCell" valign="top"><p class="docText">非限定类前面加上类或者名字空间限定，或者全局作用域解析运算符。注意一个名字本身可以是限定的，例如::X, <font face="Times New Roman"><tt>S::x</tt>, <tt>Array&lt;T&gt;::y</tt>, and <tt>::N::A&lt;T&gt;::z。</tt></font></p></td></tr><tr><td class="docTableCell" valign="top"><p class="docText">限定名</p></td><td class="docTableCell" valign="top"><p class="docText">这个名词在标准中是没有的，我们用它来表示执行限定查找的名字。特定情况下，就是限定标识或者在非限定标识前面显式使用成员访问运算符(<font face="Times New Roman"><tt>.</tt> 或者 <tt>-&gt;</tt>)。例如S::x, <tt>this-&gt;f</tt>, 和 <tt>p-&gt;A::m。然而，除了class_mem 和this-&gt;class_mem在上下文环境中是等同的情况下不需要限定名，其他情况下必须显式使用成员访问运算符。</tt></font></p></td></tr><tr><td class="docTableCell" valign="top"><p class="docText">非限定名</p></td><td class="docTableCell" valign="top"><p class="docText">非限定标识不是非限定名。这也不是一个标准中的术语，但是相当于执行非限定查找中的名字。</p></td></tr></tbody></table><br /><table cellspacing="0" cellpadding="1" width="100%" border="1"><caption><h5 class="docTableTitle">表格 9.2. <font face="Courier New">名字分类学 (第二部分)</font></h5></caption><colgroup span="2"></colgroup><tbody><tr><th class="docTableHeader" valign="top" width="80"><span class="docEmphStrong"><p class="docText"><span class="docEmphStrong">分类</span></p></span></th><th class="docTableHeader" valign="top"><span class="docEmphStrong"><p class="docText"><span class="docEmphStrong">注释</span></p></span></th></tr><tr><td class="docTableCell" valign="top"><p class="docText">名字</p></td><td class="docTableCell" valign="top"><p class="docText">限定或者非限定的名字。</p></td></tr><tr><td class="docTableCell" valign="top"><p class="docText">依赖名</p></td><td class="docTableCell" valign="top"><p class="docText">名字依赖于模板参数。任何含有模板参数的限定或者非限定名字都是依赖名。此外，成员访问操作符(<tt>.</tt>或<tt>-&gt;</tt>) 修饰的限定名 ，如果操作符左边的表达式类型依赖于模板参数，那么这个限定名是依赖的。尤其这种情况：<font face="Courier New">this-&gt;b中的b在模板中便是依赖名。最后，ident(x, y, z)调用形式中的ident当且仅当参数表达式中有类型依赖于模板参数。</font></p></td></tr><tr><td class="docTableCell" valign="top"><p class="docText">非依赖名</p></td><td class="docTableCell" valign="top"><p class="docText">不符合上面描述的名字就不是依赖名。</p></td></tr></tbody></table><br />上面这些名词通常用来描述C++模板中的问题，通读一边是很有用的，我们可以熟悉这些名词，但没有必要记住每个名词确切的意思。需要的时候，我们可以通过索引很容易的查阅。<img src ="http://www.cppblog.com/wlwlxj/aggbug/5169.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/wlwlxj/" target="_blank">万连文</a> 2006-04-08 11:38 <a href="http://www.cppblog.com/wlwlxj/archive/2006/04/08/5169.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C++ Template: The Complete Guide 学习－8.5后记</title><link>http://www.cppblog.com/wlwlxj/archive/2006/04/07/5157.html</link><dc:creator>万连文</dc:creator><author>万连文</author><pubDate>Fri, 07 Apr 2006 14:24:00 GMT</pubDate><guid>http://www.cppblog.com/wlwlxj/archive/2006/04/07/5157.html</guid><wfw:comment>http://www.cppblog.com/wlwlxj/comments/5157.html</wfw:comment><comments>http://www.cppblog.com/wlwlxj/archive/2006/04/07/5157.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/wlwlxj/comments/commentRss/5157.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/wlwlxj/services/trackbacks/5157.html</trackback:ping><description><![CDATA[
		<strong>8.5 后记</strong>
		<br />自80年代后期引入C++模板，其概念和语法一直保持相对稳定。类模板、函数模板以及类型参数。非类型参数是模板最基础的工具。<br /><br />然而，在最初设计的基础上还是添加了一些内容，大部分是C++标准库的需要。成员模板是添加内容中最基本的。很奇怪，只有成员函数模板被正式纳入C++标准，成员类模板成为标准的一部分还存在争议。<br /><br />友元模板、缺省模板参数和模板模板参数都是最近才添加进语言中的。声明模板模板参数有时候称作高级泛性，它们最初被引入在C++标准库中提供一种分配器模型，后来这种分配器模型被其它不依赖模板模板参数所替代。由于模板模板参数规格说明到标准化进程后期仍不完善，几乎要被从语言中剔除。最终由于C++标准委员会大部分成员赞成保留下来并完成了规格说明。<img src ="http://www.cppblog.com/wlwlxj/aggbug/5157.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/wlwlxj/" target="_blank">万连文</a> 2006-04-07 22:24 <a href="http://www.cppblog.com/wlwlxj/archive/2006/04/07/5157.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C++ Template: The Complete Guide 学习－8.4友元</title><link>http://www.cppblog.com/wlwlxj/archive/2006/04/06/5119.html</link><dc:creator>万连文</dc:creator><author>万连文</author><pubDate>Thu, 06 Apr 2006 15:48:00 GMT</pubDate><guid>http://www.cppblog.com/wlwlxj/archive/2006/04/06/5119.html</guid><wfw:comment>http://www.cppblog.com/wlwlxj/comments/5119.html</wfw:comment><comments>http://www.cppblog.com/wlwlxj/archive/2006/04/06/5119.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/wlwlxj/comments/commentRss/5119.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/wlwlxj/services/trackbacks/5119.html</trackback:ping><description><![CDATA[独自一人苦学模板，实在郁闷，翻译e文逼迫自己学习：（全部写完后整理）<br /><br /><strong>8.4 友元</strong><br />声明友元的思想其实很简单：标识一个类或者函数，对于将其声明为友元所在的类具有某种特权。但是在以下两个方面，问题似乎有点复杂：<br />1、一个友元声明只能是一个实体的唯一声明（注：我还没理解，不能解释）<br />2、友元函数声明的同时可以定义。<br /><br />友元类在声明的时候不允许定义，所以一般不会有问题。在模板情况下，唯一一点不同就是可以将类模板的一个特定实例声明为友元：<br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /><span style="COLOR: #000000">template</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">typename T</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> Node;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />template</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">typename T</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br /><img id="Codehighlighter1_65_93_Open_Image" onclick="this.style.display='none'; Codehighlighter1_65_93_Open_Text.style.display='none'; Codehighlighter1_65_93_Closed_Image.style.display='inline'; Codehighlighter1_65_93_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_65_93_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_65_93_Closed_Text.style.display='none'; Codehighlighter1_65_93_Open_Image.style.display='inline'; Codehighlighter1_65_93_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align="top" /></span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> Tree</span><span id="Codehighlighter1_65_93_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/images/dot.gif" /></span><span id="Codehighlighter1_65_93_Open_Text"><span style="COLOR: #000000">{<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    friend </span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> Node</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">T</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    …<br /><img src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span></span><span style="COLOR: #000000">;</span></div>注意：类模板在被一个类或者类模板声明为友元的时候必须是可见的，而对于普通的类则没有这种需求：<br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /><span style="COLOR: #000000">template</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">typename T</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br /><img id="Codehighlighter1_31_169_Open_Image" onclick="this.style.display='none'; Codehighlighter1_31_169_Open_Text.style.display='none'; Codehighlighter1_31_169_Closed_Image.style.display='inline'; Codehighlighter1_31_169_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_31_169_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_31_169_Closed_Text.style.display='none'; Codehighlighter1_31_169_Open_Image.style.display='inline'; Codehighlighter1_31_169_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align="top" /></span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> Tree</span><span id="Codehighlighter1_31_169_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/images/dot.gif" /></span><span id="Codehighlighter1_31_169_Open_Text"><span style="COLOR: #000000">{ <br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    friend </span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> Factory;        </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> OK, even if first declaration of Factory</span><span style="COLOR: #008000"><br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" /></span><span style="COLOR: #000000">    friend </span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> Node</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">T</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">;  </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> ERROR if Node isn't visible</span><span style="COLOR: #008000"><br /><img src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" /></span><span style="COLOR: #000000">}</span></span><span style="COLOR: #000000">; </span></div><br /><strong>8.4.1 友元函数</strong><br />函数模板的实例可以通过在函数名后面跟一对&lt;&gt;将其声明为友元。&lt;&gt;里面可以包含模板参数，如果编译器可以推导出模板参数，可以省略调模板参数：<br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /><span style="COLOR: #000000">template</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">typename T1, typename T2</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> combine(T1, T2);<br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /><br /><img id="Codehighlighter1_69_429_Open_Image" onclick="this.style.display='none'; Codehighlighter1_69_429_Open_Text.style.display='none'; Codehighlighter1_69_429_Closed_Image.style.display='inline'; Codehighlighter1_69_429_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_69_429_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_69_429_Closed_Text.style.display='none'; Codehighlighter1_69_429_Open_Image.style.display='inline'; Codehighlighter1_69_429_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align="top" /></span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> Mixer</span><span id="Codehighlighter1_69_429_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/images/dot.gif" /></span><span id="Codehighlighter1_69_429_Open_Text"><span style="COLOR: #000000">{<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    friend </span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> combine</span><span style="COLOR: #000000">&lt;&gt;</span><span style="COLOR: #000000">(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">, </span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">);<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> OK: T1 = int&amp;, T2 = int&amp;</span><span style="COLOR: #008000"><br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" /></span><span style="COLOR: #000000">    friend </span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> combine</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">, </span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">, </span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">);<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> OK: T1 = int, T2 = int</span><span style="COLOR: #008000"><br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" /></span><span style="COLOR: #000000">    friend </span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> combine</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">(</span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">, </span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">);<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> OK: T1 = char T2 = int</span><span style="COLOR: #008000"><br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" /></span><span style="COLOR: #000000">    friend </span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> combine</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">(</span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">, </span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">);<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> ERROR: doesn't match combine() template</span><span style="COLOR: #008000"><br /><img id="Codehighlighter1_390_392_Open_Image" onclick="this.style.display='none'; Codehighlighter1_390_392_Open_Text.style.display='none'; Codehighlighter1_390_392_Closed_Image.style.display='inline'; Codehighlighter1_390_392_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_390_392_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_390_392_Closed_Text.style.display='none'; Codehighlighter1_390_392_Open_Image.style.display='inline'; Codehighlighter1_390_392_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedSubBlock.gif" align="top" /></span><span style="COLOR: #000000">    friend </span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> combine</span><span style="COLOR: #000000">&lt;&gt;</span><span style="COLOR: #000000">(</span><span style="COLOR: #0000ff">long</span><span style="COLOR: #000000">, </span><span style="COLOR: #0000ff">long</span><span style="COLOR: #000000">) </span><span id="Codehighlighter1_390_392_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/images/dot.gif" /></span><span id="Codehighlighter1_390_392_Open_Text"><span style="COLOR: #000000">{ }</span></span><span style="COLOR: #000000"><br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> ERROR: definition not allowed!</span><span style="COLOR: #008000"><br /><img src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" /></span><span style="COLOR: #000000">}</span></span><span style="COLOR: #000000">;</span></div>（注：在GCC下测试，VS2003不行）<br />注意：我们可以对模板进行专门化定义，但是不能对模板实例进行定义，所以声明模板实例为友元时不能定义。<br /><br />如果名字后面跟有&lt;&gt;，有2种可能：<br />1、如果名字没有限定词（也就是前面没有<font face="Courier New">::</font>），就不可能是模板实例。如果在声明友元的地方没有非模板函数匹配的话，就是函数的首次声明，声明同时可以定义。<br />2、如果名字有限定词，那么一定与前面声明的函数或者模板函数有关，在匹配的时候优先选择非函数模板而不是函数模板，然而在声明的时候是不允许定义的。<br /><br />下面的例子总结了各种可能性：<br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> multiply (</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">);   </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> ordinary function </span><span style="COLOR: #008000"><br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #000000"><br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />template </span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">typename T</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"> <br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> multiply(T);        </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> function template </span><span style="COLOR: #008000"><br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #000000"><br /><img id="Codehighlighter1_134_803_Open_Image" onclick="this.style.display='none'; Codehighlighter1_134_803_Open_Text.style.display='none'; Codehighlighter1_134_803_Closed_Image.style.display='inline'; Codehighlighter1_134_803_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_134_803_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_134_803_Closed_Text.style.display='none'; Codehighlighter1_134_803_Open_Image.style.display='inline'; Codehighlighter1_134_803_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align="top" /></span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> Comrades </span><span id="Codehighlighter1_134_803_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/images/dot.gif" /></span><span id="Codehighlighter1_134_803_Open_Text"><span style="COLOR: #000000">{ <br /><img id="Codehighlighter1_167_168_Open_Image" onclick="this.style.display='none'; Codehighlighter1_167_168_Open_Text.style.display='none'; Codehighlighter1_167_168_Closed_Image.style.display='inline'; Codehighlighter1_167_168_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_167_168_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_167_168_Closed_Text.style.display='none'; Codehighlighter1_167_168_Open_Image.style.display='inline'; Codehighlighter1_167_168_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />    friend </span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> multiply(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">) </span><span id="Codehighlighter1_167_168_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/images/dot.gif" /></span><span id="Codehighlighter1_167_168_Open_Text"><span style="COLOR: #000000">{}</span></span><span style="COLOR: #000000"> <br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />                         </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> defines a new function ::multiply(int) </span><span style="COLOR: #008000"><br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" /></span><span style="COLOR: #000000"><br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    friend </span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> ::multiply(</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">); <br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />                         </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> refers to the ordinary function above; <br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />                         </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> not to the multiply&lt;void*&gt; instance </span><span style="COLOR: #008000"><br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" /></span><span style="COLOR: #000000"><br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    friend </span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> ::multiply(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">); <br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />                         </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> refers to an instance of the template </span><span style="COLOR: #008000"><br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" /></span><span style="COLOR: #000000"><br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    friend </span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> ::multiply</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">double</span><span style="COLOR: #000000">*&gt;</span><span style="COLOR: #000000">(</span><span style="COLOR: #0000ff">double</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">); <br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />                         </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> qualified names can also have angle brackets <br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />                         </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> but a template must be visible. </span><span style="COLOR: #008000"><br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" /></span><span style="COLOR: #000000"><br /><img id="Codehighlighter1_721_722_Open_Image" onclick="this.style.display='none'; Codehighlighter1_721_722_Open_Text.style.display='none'; Codehighlighter1_721_722_Closed_Image.style.display='inline'; Codehighlighter1_721_722_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_721_722_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_721_722_Closed_Text.style.display='none'; Codehighlighter1_721_722_Open_Image.style.display='inline'; Codehighlighter1_721_722_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />    friend </span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> ::error() </span><span id="Codehighlighter1_721_722_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/images/dot.gif" /></span><span id="Codehighlighter1_721_722_Open_Text"><span style="COLOR: #000000">{}</span></span><span style="COLOR: #000000"> <br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />                         </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> ERROR: a qualified friend cannot be a definition </span><span style="COLOR: #008000"><br /><img src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" /></span><span style="COLOR: #000000">}</span></span><span style="COLOR: #000000">; </span></div><br />（注：在VS2003和规则复合，GCC上编译完全通过）<br /><br />前面例子我们讨论了一般类（相对于类模板）里面的友元函数，遵守的规则同样适用于类模板，但模板参数在确定友元函数的时候会起作用：<br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /><span style="COLOR: #000000">template</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">typename T</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br /><img id="Codehighlighter1_32_59_Open_Image" onclick="this.style.display='none'; Codehighlighter1_32_59_Open_Text.style.display='none'; Codehighlighter1_32_59_Closed_Image.style.display='inline'; Codehighlighter1_32_59_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_32_59_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_32_59_Closed_Text.style.display='none'; Codehighlighter1_32_59_Open_Image.style.display='inline'; Codehighlighter1_32_59_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align="top" /></span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> Node </span><span id="Codehighlighter1_32_59_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/images/dot.gif" /></span><span id="Codehighlighter1_32_59_Open_Text"><span style="COLOR: #000000">{<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    Node</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">T</span><span style="COLOR: #000000">&gt;*</span><span style="COLOR: #000000"> allocate();<br /><img src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span></span><span style="COLOR: #000000">; <br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />template</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">typename T</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br /><img id="Codehighlighter1_96_139_Open_Image" onclick="this.style.display='none'; Codehighlighter1_96_139_Open_Text.style.display='none'; Codehighlighter1_96_139_Closed_Image.style.display='inline'; Codehighlighter1_96_139_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_96_139_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_96_139_Closed_Text.style.display='none'; Codehighlighter1_96_139_Open_Image.style.display='inline'; Codehighlighter1_96_139_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align="top" /></span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> List </span><span id="Codehighlighter1_96_139_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/images/dot.gif" /></span><span id="Codehighlighter1_96_139_Open_Text"><span style="COLOR: #000000">{<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    friend Node</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">T</span><span style="COLOR: #000000">&gt;*</span><span style="COLOR: #000000"> Node</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">T</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">::allocate();<br /><img src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span></span><span style="COLOR: #000000">;</span></div><br />然而，当友元函数在类模板里面声明并定义的时候会出现有趣的现象，因为模板里面任何东西在未实例化之前都只是声明而没有具现。考虑下面的例子：<br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /><span style="COLOR: #000000">template</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">typename T</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br /><img id="Codehighlighter1_35_184_Open_Image" onclick="this.style.display='none'; Codehighlighter1_35_184_Open_Text.style.display='none'; Codehighlighter1_35_184_Closed_Image.style.display='inline'; Codehighlighter1_35_184_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_35_184_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_35_184_Closed_Text.style.display='none'; Codehighlighter1_35_184_Open_Image.style.display='inline'; Codehighlighter1_35_184_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align="top" /></span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> Creator </span><span id="Codehighlighter1_35_184_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/images/dot.gif" /></span><span id="Codehighlighter1_35_184_Open_Text"><span style="COLOR: #000000">{ <br /><img id="Codehighlighter1_63_182_Open_Image" onclick="this.style.display='none'; Codehighlighter1_63_182_Open_Text.style.display='none'; Codehighlighter1_63_182_Closed_Image.style.display='inline'; Codehighlighter1_63_182_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_63_182_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_63_182_Closed_Text.style.display='none'; Codehighlighter1_63_182_Open_Image.style.display='inline'; Codehighlighter1_63_182_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />    friend </span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> appear() </span><span id="Codehighlighter1_63_182_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/images/dot.gif" /></span><span id="Codehighlighter1_63_182_Open_Text"><span style="COLOR: #000000">{  </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> a new function ::appear(), but it doesn't</span><span style="COLOR: #008000"><br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" /></span><span style="COLOR: #000000">        …                   </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> exist until Creator is instantiated</span><span style="COLOR: #008000"><br /><img src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" /></span><span style="COLOR: #000000">    }</span></span><span style="COLOR: #000000"><br /><img src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span></span><span style="COLOR: #000000">;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />Creator</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"> miracle;  </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> ::appear() is created at this point</span><span style="COLOR: #008000"><br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #000000">Creator</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">double</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"> oops;   </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> ERROR: ::appear() is created a second time!</span></div>这个例子中模板的两次实例化导致同一函数定义多次，违反了一次定义规则。<br /><br />所以对于上面的情况，我们必须确保类模板的模板参数出现在声明并定义的友元函数形参里面（除非想阻止多次实例化一个类模板，这好像不太可能）。把这个规律运用到前面那个例子：<br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /><span style="COLOR: #000000">template</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">typename T</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br /><img id="Codehighlighter1_35_143_Open_Image" onclick="this.style.display='none'; Codehighlighter1_35_143_Open_Text.style.display='none'; Codehighlighter1_35_143_Closed_Image.style.display='inline'; Codehighlighter1_35_143_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_35_143_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_35_143_Closed_Text.style.display='none'; Codehighlighter1_35_143_Open_Image.style.display='inline'; Codehighlighter1_35_143_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align="top" /></span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> Creator </span><span id="Codehighlighter1_35_143_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/images/dot.gif" /></span><span id="Codehighlighter1_35_143_Open_Text"><span style="COLOR: #000000">{ <br /><img id="Codehighlighter1_71_141_Open_Image" onclick="this.style.display='none'; Codehighlighter1_71_141_Open_Text.style.display='none'; Codehighlighter1_71_141_Closed_Image.style.display='inline'; Codehighlighter1_71_141_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_71_141_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_71_141_Closed_Text.style.display='none'; Codehighlighter1_71_141_Open_Image.style.display='inline'; Codehighlighter1_71_141_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />    friend </span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> feed(Creator</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">T</span><span style="COLOR: #000000">&gt;*</span><span style="COLOR: #000000">)</span><span id="Codehighlighter1_71_141_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/images/dot.gif" /></span><span id="Codehighlighter1_71_141_Open_Text"><span style="COLOR: #000000">{  </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> every T generates a different<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />                                    </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> function ::feed()</span><span style="COLOR: #008000"><br /><img src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" /></span><span style="COLOR: #000000">    }</span></span><span style="COLOR: #000000"><br /><img src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span></span><span style="COLOR: #000000">;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />Creator</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"> one;     </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> generates ::feed(Creator&lt;void&gt;*)</span><span style="COLOR: #008000"><br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #000000">Creator</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">double</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"> two;   </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> generates ::feed(Creator&lt;double&gt;*)</span></div>这个例子中，Creator每个实例都生成不同的函数。注意这些函数是类模板实例产生的，但函数本身并不是函数模板的实例，而是普通函数。<br />还要注意这些函数体定义于类中，默认是内联的，所以在两个翻译单元产生相同的函数是没有问题的。（注：由于内联函数基于代码替代技术，所以一个函数定义所在的h文件被多次包含不会有问题，内联函数在编译器看来就是一段代码。）<br /><br /><strong>8.4.2 友元模板<br /></strong>一般情况我们都是把函数模板或者类模板的某一实例声明为友元，但把模板本身声明为友元有时候也是非常有用的。这就需要所谓的模板友元，例如：<br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img id="Codehighlighter1_14_242_Open_Image" onclick="this.style.display='none'; Codehighlighter1_14_242_Open_Text.style.display='none'; Codehighlighter1_14_242_Closed_Image.style.display='inline'; Codehighlighter1_14_242_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_14_242_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_14_242_Closed_Text.style.display='none'; Codehighlighter1_14_242_Open_Image.style.display='inline'; Codehighlighter1_14_242_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align="top" /><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> Manager </span><span id="Codehighlighter1_14_242_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/images/dot.gif" /></span><span id="Codehighlighter1_14_242_Open_Text"><span style="COLOR: #000000">{ <br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    template</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">typename T</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    friend </span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> Task;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    <br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    template</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">typename T</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    friend </span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> Schedule</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">T</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">::dispatch(Task</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">T</span><span style="COLOR: #000000">&gt;*</span><span style="COLOR: #000000">);<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    <br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    template</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">typename T</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br /><img id="Codehighlighter1_183_215_Open_Image" onclick="this.style.display='none'; Codehighlighter1_183_215_Open_Text.style.display='none'; Codehighlighter1_183_215_Closed_Image.style.display='inline'; Codehighlighter1_183_215_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_183_215_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_183_215_Closed_Text.style.display='none'; Codehighlighter1_183_215_Open_Image.style.display='inline'; Codehighlighter1_183_215_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />    friend </span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> ticket() </span><span id="Codehighlighter1_183_215_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/images/dot.gif" /></span><span id="Codehighlighter1_183_215_Open_Text"><span style="COLOR: #000000">{<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />        </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">++</span><span style="COLOR: #000000">Manager::counter;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />    }</span></span><span style="COLOR: #000000"> <br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    </span><span style="COLOR: #0000ff">static</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> counter;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span></span><span style="COLOR: #000000">;</span></div>和普通友元函数一样，没有限定词且名字后面没有&lt;&gt;的函数模板在声明为友元同时可以定义。<br />声明原始函数模板或者原始类模板为友元的时候，所有相关的偏特化以及显示特例化都自动成为友元。<br />（注：测试代码<br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img id="Codehighlighter1_14_98_Open_Image" onclick="this.style.display='none'; Codehighlighter1_14_98_Open_Text.style.display='none'; Codehighlighter1_14_98_Closed_Image.style.display='inline'; Codehighlighter1_14_98_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_14_98_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_14_98_Closed_Text.style.display='none'; Codehighlighter1_14_98_Open_Image.style.display='inline'; Codehighlighter1_14_98_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align="top" /><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> Manager </span><span id="Codehighlighter1_14_98_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/images/dot.gif" /></span><span id="Codehighlighter1_14_98_Open_Text"><span style="COLOR: #000000">{ <br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    template</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">typename T</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">    </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> firend template</span><span style="COLOR: #008000"><br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" /></span><span style="COLOR: #000000">    friend </span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> Task;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" /></span><span style="COLOR: #0000ff">private</span><span style="COLOR: #000000">:<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    </span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">    _dat;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span></span><span style="COLOR: #000000">;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />template</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">typename T</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br /><img id="Codehighlighter1_134_136_Open_Image" onclick="this.style.display='none'; Codehighlighter1_134_136_Open_Text.style.display='none'; Codehighlighter1_134_136_Closed_Image.style.display='inline'; Codehighlighter1_134_136_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_134_136_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_134_136_Closed_Text.style.display='none'; Codehighlighter1_134_136_Open_Image.style.display='inline'; Codehighlighter1_134_136_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align="top" /></span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> Task </span><span id="Codehighlighter1_134_136_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/images/dot.gif" /></span><span id="Codehighlighter1_134_136_Open_Text"><span style="COLOR: #000000">{<br /><img src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span></span><span style="COLOR: #000000">;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />template</span><span style="COLOR: #000000">&lt;&gt;</span><span style="COLOR: #000000"><br /><img id="Codehighlighter1_167_308_Open_Image" onclick="this.style.display='none'; Codehighlighter1_167_308_Open_Text.style.display='none'; Codehighlighter1_167_308_Closed_Image.style.display='inline'; Codehighlighter1_167_308_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_167_308_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_167_308_Closed_Text.style.display='none'; Codehighlighter1_167_308_Open_Image.style.display='inline'; Codehighlighter1_167_308_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align="top" /></span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> Task</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"> </span><span id="Codehighlighter1_167_308_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/images/dot.gif" /></span><span id="Codehighlighter1_167_308_Open_Text"><span style="COLOR: #000000">{            </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> specialization</span><span style="COLOR: #008000"><br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" /></span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">:<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    </span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> accessData()<br /><img id="Codehighlighter1_217_278_Open_Image" onclick="this.style.display='none'; Codehighlighter1_217_278_Open_Text.style.display='none'; Codehighlighter1_217_278_Closed_Image.style.display='inline'; Codehighlighter1_217_278_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_217_278_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_217_278_Closed_Text.style.display='none'; Codehighlighter1_217_278_Open_Image.style.display='inline'; Codehighlighter1_217_278_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />    </span><span id="Codehighlighter1_217_278_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/images/dot.gif" /></span><span id="Codehighlighter1_217_278_Open_Text"><span style="COLOR: #000000">{<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />        _manager._dat </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;    </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> can access Manager's private data</span><span style="COLOR: #008000"><br /><img src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" /></span><span style="COLOR: #000000">    }</span></span><span style="COLOR: #000000"><br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" /></span><span style="COLOR: #0000ff">private</span><span style="COLOR: #000000">:<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    Manager    _manager;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span></span><span style="COLOR: #000000">;</span></div><br />）<br />(本节完，汗...... 自己收获不小)<img src ="http://www.cppblog.com/wlwlxj/aggbug/5119.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/wlwlxj/" target="_blank">万连文</a> 2006-04-06 23:48 <a href="http://www.cppblog.com/wlwlxj/archive/2006/04/06/5119.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>能生成这个类的一个对象嘛？？？</title><link>http://www.cppblog.com/wlwlxj/archive/2006/04/05/5052.html</link><dc:creator>万连文</dc:creator><author>万连文</author><pubDate>Wed, 05 Apr 2006 15:24:00 GMT</pubDate><guid>http://www.cppblog.com/wlwlxj/archive/2006/04/05/5052.html</guid><wfw:comment>http://www.cppblog.com/wlwlxj/comments/5052.html</wfw:comment><comments>http://www.cppblog.com/wlwlxj/archive/2006/04/05/5052.html#Feedback</comments><slash:comments>12</slash:comments><wfw:commentRss>http://www.cppblog.com/wlwlxj/comments/commentRss/5052.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/wlwlxj/services/trackbacks/5052.html</trackback:ping><description><![CDATA[不谈适用性，纯粹语法上实现，我自己无能为力。<br /><br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /><span style="COLOR: #000000">template</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">typename T, template</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">T a</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> T2</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> TmTm<br /><img id="Codehighlighter1_56_58_Open_Image" onclick="this.style.display='none'; Codehighlighter1_56_58_Open_Text.style.display='none'; Codehighlighter1_56_58_Closed_Image.style.display='inline'; Codehighlighter1_56_58_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_56_58_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_56_58_Closed_Text.style.display='none'; Codehighlighter1_56_58_Open_Image.style.display='inline'; Codehighlighter1_56_58_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align="top" /></span><span id="Codehighlighter1_56_58_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/images/dot.gif" /></span><span id="Codehighlighter1_56_58_Open_Text"><span style="COLOR: #000000">{<br /><img src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span></span><span style="COLOR: #000000">;</span></div><img src ="http://www.cppblog.com/wlwlxj/aggbug/5052.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/wlwlxj/" target="_blank">万连文</a> 2006-04-05 23:24 <a href="http://www.cppblog.com/wlwlxj/archive/2006/04/05/5052.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>一个模板巧妙技术，语法技巧</title><link>http://www.cppblog.com/wlwlxj/archive/2006/04/05/5051.html</link><dc:creator>万连文</dc:creator><author>万连文</author><pubDate>Wed, 05 Apr 2006 14:26:00 GMT</pubDate><guid>http://www.cppblog.com/wlwlxj/archive/2006/04/05/5051.html</guid><wfw:comment>http://www.cppblog.com/wlwlxj/comments/5051.html</wfw:comment><comments>http://www.cppblog.com/wlwlxj/archive/2006/04/05/5051.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.cppblog.com/wlwlxj/comments/commentRss/5051.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/wlwlxj/services/trackbacks/5051.html</trackback:ping><description><![CDATA[
		<p>研究Boost前，想深入了解一下模板技术，找来一本书《C++ Template:The Complete Guide》研究。<br />里面有这样一个小技巧，判断一个类中是否有某种类形。下面是代码：(Win 2K+ VS2003)<br /></p>
		<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee">
				<img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />
				<span style="COLOR: #000000">#include </span>
				<span style="COLOR: #000000">&lt;</span>
				<span style="COLOR: #000000">iostream</span>
				<span style="COLOR: #000000">&gt;</span>
				<span style="COLOR: #000000">
						<br />
						<img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />
						<br />
						<img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />
				</span>
				<span style="COLOR: #008000">//</span>
				<span style="COLOR: #008000"> 返回类型,大小分别为1、2</span>
				<span style="COLOR: #008000">
						<br />
						<img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />
				</span>
				<span style="COLOR: #000000">typedef </span>
				<span style="COLOR: #0000ff">char</span>
				<span style="COLOR: #000000"> RT1;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />typedef </span>
				<span style="COLOR: #0000ff">struct</span>
				<span style="COLOR: #000000">
						<br />
						<img id="Codehighlighter1_71_85_Open_Image" onclick="this.style.display='none'; Codehighlighter1_71_85_Open_Text.style.display='none'; Codehighlighter1_71_85_Closed_Image.style.display='inline'; Codehighlighter1_71_85_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" />
						<img id="Codehighlighter1_71_85_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_71_85_Closed_Text.style.display='none'; Codehighlighter1_71_85_Open_Image.style.display='inline'; Codehighlighter1_71_85_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align="top" />
				</span>
				<span id="Codehighlighter1_71_85_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">
						<img src="http://www.cppblog.com/images/dot.gif" />
				</span>
				<span id="Codehighlighter1_71_85_Open_Text">
						<span style="COLOR: #000000">{<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    </span>
						<span style="COLOR: #0000ff">char</span>
						<span style="COLOR: #000000"> a[</span>
						<span style="COLOR: #000000">2</span>
						<span style="COLOR: #000000">];<br /><img src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span>
				</span>
				<span style="COLOR: #000000"> RT2;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /></span>
				<span style="COLOR: #008000">//</span>
				<span style="COLOR: #008000"> 选择这个版本将返回char,大小为1</span>
				<span style="COLOR: #008000">
						<br />
						<img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />
				</span>
				<span style="COLOR: #000000">template</span>
				<span style="COLOR: #000000">&lt;</span>
				<span style="COLOR: #000000">typename T</span>
				<span style="COLOR: #000000">&gt;</span>
				<span style="COLOR: #000000"> RT1 test(typename T::X </span>
				<span style="COLOR: #0000ff">const</span>
				<span style="COLOR: #000000">*</span>
				<span style="COLOR: #000000">)<br /><img id="Codehighlighter1_167_193_Open_Image" onclick="this.style.display='none'; Codehighlighter1_167_193_Open_Text.style.display='none'; Codehighlighter1_167_193_Closed_Image.style.display='inline'; Codehighlighter1_167_193_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_167_193_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_167_193_Closed_Text.style.display='none'; Codehighlighter1_167_193_Open_Image.style.display='inline'; Codehighlighter1_167_193_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align="top" /></span>
				<span id="Codehighlighter1_167_193_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">
						<img src="http://www.cppblog.com/images/dot.gif" />
				</span>
				<span id="Codehighlighter1_167_193_Open_Text">
						<span style="COLOR: #000000">{<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    </span>
						<span style="COLOR: #0000ff">int</span>
						<span style="COLOR: #000000">    dumy    </span>
						<span style="COLOR: #000000">=</span>
						<span style="COLOR: #000000"> </span>
						<span style="COLOR: #000000">0</span>
						<span style="COLOR: #000000">;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    dumy</span>
						<span style="COLOR: #000000">++</span>
						<span style="COLOR: #000000">;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span>
				</span>
				<span style="COLOR: #000000">
						<br />
						<img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />
						<br />
						<img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />
				</span>
				<span style="COLOR: #008000">//</span>
				<span style="COLOR: #008000"> 选择这个版本将返回char,大小为2</span>
				<span style="COLOR: #008000">
						<br />
						<img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />
				</span>
				<span style="COLOR: #000000">template</span>
				<span style="COLOR: #000000">&lt;</span>
				<span style="COLOR: #000000">typename T</span>
				<span style="COLOR: #000000">&gt;</span>
				<span style="COLOR: #000000"> RT2 test(<img src="http://www.cppblog.com/images/dot.gif" />)<br /><img id="Codehighlighter1_253_279_Open_Image" onclick="this.style.display='none'; Codehighlighter1_253_279_Open_Text.style.display='none'; Codehighlighter1_253_279_Closed_Image.style.display='inline'; Codehighlighter1_253_279_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_253_279_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_253_279_Closed_Text.style.display='none'; Codehighlighter1_253_279_Open_Image.style.display='inline'; Codehighlighter1_253_279_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align="top" /></span>
				<span id="Codehighlighter1_253_279_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">
						<img src="http://www.cppblog.com/images/dot.gif" />
				</span>
				<span id="Codehighlighter1_253_279_Open_Text">
						<span style="COLOR: #000000">{<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    </span>
						<span style="COLOR: #0000ff">int</span>
						<span style="COLOR: #000000">    dumy    </span>
						<span style="COLOR: #000000">=</span>
						<span style="COLOR: #000000"> </span>
						<span style="COLOR: #000000">0</span>
						<span style="COLOR: #000000">;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    dumy</span>
						<span style="COLOR: #000000">++</span>
						<span style="COLOR: #000000">;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span>
				</span>
				<span style="COLOR: #000000">
						<br />
						<img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />
						<br />
						<img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />
				</span>
				<span style="COLOR: #008000">//</span>
				<span style="COLOR: #008000"> 依靠编译器自动选择test函数,然后依据返回类型判断是否含有X</span>
				<span style="COLOR: #008000">
						<br />
						<img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />
				</span>
				<span style="COLOR: #000000">template</span>
				<span style="COLOR: #000000">&lt;</span>
				<span style="COLOR: #000000">typename T</span>
				<span style="COLOR: #000000">&gt;</span>
				<span style="COLOR: #000000">
						<br />
						<img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />
				</span>
				<span style="COLOR: #0000ff">bool</span>
				<span style="COLOR: #000000"> type_has_member_type_X()<br /><img id="Codehighlighter1_369_441_Open_Image" onclick="this.style.display='none'; Codehighlighter1_369_441_Open_Text.style.display='none'; Codehighlighter1_369_441_Closed_Image.style.display='inline'; Codehighlighter1_369_441_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_369_441_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_369_441_Closed_Text.style.display='none'; Codehighlighter1_369_441_Open_Image.style.display='inline'; Codehighlighter1_369_441_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align="top" /></span>
				<span id="Codehighlighter1_369_441_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">
						<img src="http://www.cppblog.com/images/dot.gif" />
				</span>
				<span id="Codehighlighter1_369_441_Open_Text">
						<span style="COLOR: #000000">{<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    </span>
						<span style="COLOR: #0000ff">return</span>
						<span style="COLOR: #000000"> (</span>
						<span style="COLOR: #0000ff">sizeof</span>
						<span style="COLOR: #000000">(test</span>
						<span style="COLOR: #000000">&lt;</span>
						<span style="COLOR: #000000">T</span>
						<span style="COLOR: #000000">&gt;</span>
						<span style="COLOR: #000000">(</span>
						<span style="COLOR: #000000">0</span>
						<span style="COLOR: #000000">)) </span>
						<span style="COLOR: #000000">==</span>
						<span style="COLOR: #000000"> </span>
						<span style="COLOR: #000000">1</span>
						<span style="COLOR: #000000">);<br /><img src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span>
				</span>
				<span style="COLOR: #000000">
						<br />
						<img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />
						<br />
						<img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />
				</span>
				<span style="COLOR: #008000">//</span>
				<span style="COLOR: #008000"> 有X类型的类</span>
				<span style="COLOR: #008000">
						<br />
						<img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />
				</span>
				<span style="COLOR: #0000ff">class</span>
				<span style="COLOR: #000000"> HasX<br /><img id="Codehighlighter1_465_491_Open_Image" onclick="this.style.display='none'; Codehighlighter1_465_491_Open_Text.style.display='none'; Codehighlighter1_465_491_Closed_Image.style.display='inline'; Codehighlighter1_465_491_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_465_491_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_465_491_Closed_Text.style.display='none'; Codehighlighter1_465_491_Open_Image.style.display='inline'; Codehighlighter1_465_491_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align="top" /></span>
				<span id="Codehighlighter1_465_491_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">
						<img src="http://www.cppblog.com/images/dot.gif" />
				</span>
				<span id="Codehighlighter1_465_491_Open_Text">
						<span style="COLOR: #000000">{<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" /></span>
						<span style="COLOR: #0000ff">public</span>
						<span style="COLOR: #000000">:<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    </span>
						<span style="COLOR: #0000ff">class</span>
						<span style="COLOR: #000000"> X<br /><img id="Codehighlighter1_485_488_Open_Image" onclick="this.style.display='none'; Codehighlighter1_485_488_Open_Text.style.display='none'; Codehighlighter1_485_488_Closed_Image.style.display='inline'; Codehighlighter1_485_488_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_485_488_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_485_488_Closed_Text.style.display='none'; Codehighlighter1_485_488_Open_Image.style.display='inline'; Codehighlighter1_485_488_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />    </span>
						<span id="Codehighlighter1_485_488_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">
								<img src="http://www.cppblog.com/images/dot.gif" />
						</span>
						<span id="Codehighlighter1_485_488_Open_Text">
								<span style="COLOR: #000000">{<br /><img src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />    }</span>
						</span>
						<span style="COLOR: #000000">;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span>
				</span>
				<span style="COLOR: #000000">;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /></span>
				<span style="COLOR: #008000">//</span>
				<span style="COLOR: #008000"> 无X类型的类</span>
				<span style="COLOR: #008000">
						<br />
						<img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />
				</span>
				<span style="COLOR: #0000ff">class</span>
				<span style="COLOR: #000000"> NonX<br /><img id="Codehighlighter1_516_542_Open_Image" onclick="this.style.display='none'; Codehighlighter1_516_542_Open_Text.style.display='none'; Codehighlighter1_516_542_Closed_Image.style.display='inline'; Codehighlighter1_516_542_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_516_542_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_516_542_Closed_Text.style.display='none'; Codehighlighter1_516_542_Open_Image.style.display='inline'; Codehighlighter1_516_542_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align="top" /></span>
				<span id="Codehighlighter1_516_542_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">
						<img src="http://www.cppblog.com/images/dot.gif" />
				</span>
				<span id="Codehighlighter1_516_542_Open_Text">
						<span style="COLOR: #000000">{<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" /></span>
						<span style="COLOR: #0000ff">public</span>
						<span style="COLOR: #000000">:<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    </span>
						<span style="COLOR: #0000ff">class</span>
						<span style="COLOR: #000000"> Y<br /><img id="Codehighlighter1_536_539_Open_Image" onclick="this.style.display='none'; Codehighlighter1_536_539_Open_Text.style.display='none'; Codehighlighter1_536_539_Closed_Image.style.display='inline'; Codehighlighter1_536_539_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_536_539_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_536_539_Closed_Text.style.display='none'; Codehighlighter1_536_539_Open_Image.style.display='inline'; Codehighlighter1_536_539_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />    </span>
						<span id="Codehighlighter1_536_539_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">
								<img src="http://www.cppblog.com/images/dot.gif" />
						</span>
						<span id="Codehighlighter1_536_539_Open_Text">
								<span style="COLOR: #000000">{<br /><img src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />    }</span>
						</span>
						<span style="COLOR: #000000">;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span>
				</span>
				<span style="COLOR: #000000">;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /></span>
				<span style="COLOR: #0000ff">int</span>
				<span style="COLOR: #000000"> _tmain(</span>
				<span style="COLOR: #0000ff">int</span>
				<span style="COLOR: #000000"> argc, _TCHAR</span>
				<span style="COLOR: #000000">*</span>
				<span style="COLOR: #000000"> argv[])<br /><img id="Codehighlighter1_583_934_Open_Image" onclick="this.style.display='none'; Codehighlighter1_583_934_Open_Text.style.display='none'; Codehighlighter1_583_934_Closed_Image.style.display='inline'; Codehighlighter1_583_934_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_583_934_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_583_934_Closed_Text.style.display='none'; Codehighlighter1_583_934_Open_Image.style.display='inline'; Codehighlighter1_583_934_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align="top" /></span>
				<span id="Codehighlighter1_583_934_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">
						<img src="http://www.cppblog.com/images/dot.gif" />
				</span>
				<span id="Codehighlighter1_583_934_Open_Text">
						<span style="COLOR: #000000">{<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    </span>
						<span style="COLOR: #008000">//</span>
						<span style="COLOR: #008000"> 编译器选择重载函数策略:选择类型最匹配版本<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    </span>
						<span style="COLOR: #008000">//</span>
						<span style="COLOR: #008000"> 倾向于把0转化为常量空指针,所以选择返回为RT1版本</span>
						<span style="COLOR: #008000">
								<br />
								<img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />
						</span>
						<span style="COLOR: #000000">    </span>
						<span style="COLOR: #0000ff">if</span>
						<span style="COLOR: #000000">(type_has_member_type_X</span>
						<span style="COLOR: #000000">&lt;</span>
						<span style="COLOR: #000000">HasX</span>
						<span style="COLOR: #000000">&gt;</span>
						<span style="COLOR: #000000">())<br /><img id="Codehighlighter1_679_719_Open_Image" onclick="this.style.display='none'; Codehighlighter1_679_719_Open_Text.style.display='none'; Codehighlighter1_679_719_Closed_Image.style.display='inline'; Codehighlighter1_679_719_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_679_719_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_679_719_Closed_Text.style.display='none'; Codehighlighter1_679_719_Open_Image.style.display='inline'; Codehighlighter1_679_719_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />    </span>
						<span id="Codehighlighter1_679_719_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">
								<img src="http://www.cppblog.com/images/dot.gif" />
						</span>
						<span id="Codehighlighter1_679_719_Open_Text">
								<span style="COLOR: #000000">{<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />        std::cout </span>
								<span style="COLOR: #000000">&lt;&lt;</span>
								<span style="COLOR: #000000"> </span>
								<span style="COLOR: #000000">"</span>
								<span style="COLOR: #000000">Has X</span>
								<span style="COLOR: #000000">"</span>
								<span style="COLOR: #000000"> </span>
								<span style="COLOR: #000000">&lt;&lt;</span>
								<span style="COLOR: #000000"> std::endl;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />    }</span>
						</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    </span>
						<span style="COLOR: #0000ff">else</span>
						<span style="COLOR: #000000">
								<br />
								<img id="Codehighlighter1_728_768_Open_Image" onclick="this.style.display='none'; Codehighlighter1_728_768_Open_Text.style.display='none'; Codehighlighter1_728_768_Closed_Image.style.display='inline'; Codehighlighter1_728_768_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" />
								<img id="Codehighlighter1_728_768_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_728_768_Closed_Text.style.display='none'; Codehighlighter1_728_768_Open_Image.style.display='inline'; Codehighlighter1_728_768_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />    </span>
						<span id="Codehighlighter1_728_768_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">
								<img src="http://www.cppblog.com/images/dot.gif" />
						</span>
						<span id="Codehighlighter1_728_768_Open_Text">
								<span style="COLOR: #000000">{<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />        std::cout </span>
								<span style="COLOR: #000000">&lt;&lt;</span>
								<span style="COLOR: #000000"> </span>
								<span style="COLOR: #000000">"</span>
								<span style="COLOR: #000000">Non X</span>
								<span style="COLOR: #000000">"</span>
								<span style="COLOR: #000000"> </span>
								<span style="COLOR: #000000">&lt;&lt;</span>
								<span style="COLOR: #000000"> std::endl;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />    }</span>
						</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />
								<br />
								<img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    </span>
						<span style="COLOR: #008000">//</span>
						<span style="COLOR: #008000"> 没有T::X,所以选择返回为RT2版本</span>
						<span style="COLOR: #008000">
								<br />
								<img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />
						</span>
						<span style="COLOR: #000000">    </span>
						<span style="COLOR: #0000ff">if</span>
						<span style="COLOR: #000000">(type_has_member_type_X</span>
						<span style="COLOR: #000000">&lt;</span>
						<span style="COLOR: #000000">NonX</span>
						<span style="COLOR: #000000">&gt;</span>
						<span style="COLOR: #000000">())<br /><img id="Codehighlighter1_832_872_Open_Image" onclick="this.style.display='none'; Codehighlighter1_832_872_Open_Text.style.display='none'; Codehighlighter1_832_872_Closed_Image.style.display='inline'; Codehighlighter1_832_872_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_832_872_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_832_872_Closed_Text.style.display='none'; Codehighlighter1_832_872_Open_Image.style.display='inline'; Codehighlighter1_832_872_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />    </span>
						<span id="Codehighlighter1_832_872_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">
								<img src="http://www.cppblog.com/images/dot.gif" />
						</span>
						<span id="Codehighlighter1_832_872_Open_Text">
								<span style="COLOR: #000000">{<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />        std::cout </span>
								<span style="COLOR: #000000">&lt;&lt;</span>
								<span style="COLOR: #000000"> </span>
								<span style="COLOR: #000000">"</span>
								<span style="COLOR: #000000">Has X</span>
								<span style="COLOR: #000000">"</span>
								<span style="COLOR: #000000"> </span>
								<span style="COLOR: #000000">&lt;&lt;</span>
								<span style="COLOR: #000000"> std::endl;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />    }</span>
						</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    </span>
						<span style="COLOR: #0000ff">else</span>
						<span style="COLOR: #000000">
								<br />
								<img id="Codehighlighter1_881_921_Open_Image" onclick="this.style.display='none'; Codehighlighter1_881_921_Open_Text.style.display='none'; Codehighlighter1_881_921_Closed_Image.style.display='inline'; Codehighlighter1_881_921_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" />
								<img id="Codehighlighter1_881_921_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_881_921_Closed_Text.style.display='none'; Codehighlighter1_881_921_Open_Image.style.display='inline'; Codehighlighter1_881_921_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />    </span>
						<span id="Codehighlighter1_881_921_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">
								<img src="http://www.cppblog.com/images/dot.gif" />
						</span>
						<span id="Codehighlighter1_881_921_Open_Text">
								<span style="COLOR: #000000">{<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />        std::cout </span>
								<span style="COLOR: #000000">&lt;&lt;</span>
								<span style="COLOR: #000000"> </span>
								<span style="COLOR: #000000">"</span>
								<span style="COLOR: #000000">Non X</span>
								<span style="COLOR: #000000">"</span>
								<span style="COLOR: #000000"> </span>
								<span style="COLOR: #000000">&lt;&lt;</span>
								<span style="COLOR: #000000"> std::endl;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />    }</span>
						</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    </span>
						<span style="COLOR: #0000ff">return</span>
						<span style="COLOR: #000000"> </span>
						<span style="COLOR: #000000">0</span>
						<span style="COLOR: #000000">;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span>
				</span>
		</div>输出结果:<br />Has X<br />Non X<img src ="http://www.cppblog.com/wlwlxj/aggbug/5051.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/wlwlxj/" target="_blank">万连文</a> 2006-04-05 22:26 <a href="http://www.cppblog.com/wlwlxj/archive/2006/04/05/5051.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>抑制模板代码膨胀的一种技术</title><link>http://www.cppblog.com/wlwlxj/archive/2006/03/27/4659.html</link><dc:creator>万连文</dc:creator><author>万连文</author><pubDate>Mon, 27 Mar 2006 10:54:00 GMT</pubDate><guid>http://www.cppblog.com/wlwlxj/archive/2006/03/27/4659.html</guid><wfw:comment>http://www.cppblog.com/wlwlxj/comments/4659.html</wfw:comment><comments>http://www.cppblog.com/wlwlxj/archive/2006/03/27/4659.html#Feedback</comments><slash:comments>7</slash:comments><wfw:commentRss>http://www.cppblog.com/wlwlxj/comments/commentRss/4659.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/wlwlxj/services/trackbacks/4659.html</trackback:ping><description><![CDATA[
		<p>模板是一种源码复用技术,在某些情况下使用它可以使代码看起来非常优雅,著名的boost库就是模板发扬的典范.<br />然而模板也存在弊端,大量使用模板可能导致代码膨胀.下面介绍一种解决的方案:</p>
		<p>我们首先看一段一般代码:<br /></p>
		<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee">
				<img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />
				<span style="COLOR: #000000">template</span>
				<span style="COLOR: #000000">&lt;</span>
				<span style="COLOR: #000000">typename T</span>
				<span style="COLOR: #000000">&gt;</span>
				<span style="COLOR: #000000">
						<br />
						<img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />
				</span>
				<span style="COLOR: #0000ff">class</span>
				<span style="COLOR: #000000"> Vector<br /><img id="Codehighlighter1_34_169_Open_Image" onclick="this.style.display='none'; Codehighlighter1_34_169_Open_Text.style.display='none'; Codehighlighter1_34_169_Closed_Image.style.display='inline'; Codehighlighter1_34_169_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_34_169_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_34_169_Closed_Text.style.display='none'; Codehighlighter1_34_169_Open_Image.style.display='inline'; Codehighlighter1_34_169_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align="top" /></span>
				<span id="Codehighlighter1_34_169_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">
						<img src="http://www.cppblog.com/images/dot.gif" />
				</span>
				<span id="Codehighlighter1_34_169_Open_Text">
						<span style="COLOR: #000000">{<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" /></span>
						<span style="COLOR: #0000ff">public</span>
						<span style="COLOR: #000000">:<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    </span>
						<span style="COLOR: #0000ff">virtual</span>
						<span style="COLOR: #000000"> </span>
						<span style="COLOR: #0000ff">void</span>
						<span style="COLOR: #000000"> Say()<br /><img id="Codehighlighter1_65_167_Open_Image" onclick="this.style.display='none'; Codehighlighter1_65_167_Open_Text.style.display='none'; Codehighlighter1_65_167_Closed_Image.style.display='inline'; Codehighlighter1_65_167_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_65_167_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_65_167_Closed_Text.style.display='none'; Codehighlighter1_65_167_Open_Image.style.display='inline'; Codehighlighter1_65_167_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />    </span>
						<span id="Codehighlighter1_65_167_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">
								<img src="http://www.cppblog.com/images/dot.gif" />
						</span>
						<span id="Codehighlighter1_65_167_Open_Text">
								<span style="COLOR: #000000">{<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />        </span>
								<span style="COLOR: #0000ff">const</span>
								<span style="COLOR: #000000"> type_info</span>
								<span style="COLOR: #000000">&amp;</span>
								<span style="COLOR: #000000">    t </span>
								<span style="COLOR: #000000">=</span>
								<span style="COLOR: #000000"> typeid(T);<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />        std::cout </span>
								<span style="COLOR: #000000">&lt;&lt;</span>
								<span style="COLOR: #000000"> </span>
								<span style="COLOR: #000000">"</span>
								<span style="COLOR: #000000">Vector&lt;</span>
								<span style="COLOR: #000000">"</span>
								<span style="COLOR: #000000"> </span>
								<span style="COLOR: #000000">&lt;&lt;</span>
								<span style="COLOR: #000000"> t.name() </span>
								<span style="COLOR: #000000">&lt;&lt;</span>
								<span style="COLOR: #000000"> </span>
								<span style="COLOR: #000000">"</span>
								<span style="COLOR: #000000">&gt;::Hello</span>
								<span style="COLOR: #000000">"</span>
								<span style="COLOR: #000000"> </span>
								<span style="COLOR: #000000">&lt;&lt;</span>
								<span style="COLOR: #000000"> std::endl;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />    }</span>
						</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span>
				</span>
				<span style="COLOR: #000000">;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /></span>
				<span style="COLOR: #008000">//</span>
				<span style="COLOR: #008000"> 特例化</span>
				<span style="COLOR: #008000">
						<br />
						<img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />
				</span>
				<span style="COLOR: #000000">template</span>
				<span style="COLOR: #000000">&lt;&gt;</span>
				<span style="COLOR: #000000">
						<br />
						<img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />
				</span>
				<span style="COLOR: #0000ff">class</span>
				<span style="COLOR: #000000">  Vector</span>
				<span style="COLOR: #000000">&lt;</span>
				<span style="COLOR: #0000ff">void</span>
				<span style="COLOR: #000000">*&gt;</span>
				<span style="COLOR: #000000">
						<br />
						<img id="Codehighlighter1_212_300_Open_Image" onclick="this.style.display='none'; Codehighlighter1_212_300_Open_Text.style.display='none'; Codehighlighter1_212_300_Closed_Image.style.display='inline'; Codehighlighter1_212_300_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" />
						<img id="Codehighlighter1_212_300_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_212_300_Closed_Text.style.display='none'; Codehighlighter1_212_300_Open_Image.style.display='inline'; Codehighlighter1_212_300_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align="top" />
				</span>
				<span id="Codehighlighter1_212_300_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">
						<img src="http://www.cppblog.com/images/dot.gif" />
				</span>
				<span id="Codehighlighter1_212_300_Open_Text">
						<span style="COLOR: #000000">{<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" /></span>
						<span style="COLOR: #0000ff">public</span>
						<span style="COLOR: #000000">:<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    </span>
						<span style="COLOR: #0000ff">virtual</span>
						<span style="COLOR: #000000"> </span>
						<span style="COLOR: #0000ff">void</span>
						<span style="COLOR: #000000"> Say()<br /><img id="Codehighlighter1_243_298_Open_Image" onclick="this.style.display='none'; Codehighlighter1_243_298_Open_Text.style.display='none'; Codehighlighter1_243_298_Closed_Image.style.display='inline'; Codehighlighter1_243_298_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_243_298_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_243_298_Closed_Text.style.display='none'; Codehighlighter1_243_298_Open_Image.style.display='inline'; Codehighlighter1_243_298_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />    </span>
						<span id="Codehighlighter1_243_298_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">
								<img src="http://www.cppblog.com/images/dot.gif" />
						</span>
						<span id="Codehighlighter1_243_298_Open_Text">
								<span style="COLOR: #000000">{<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />        std::cout </span>
								<span style="COLOR: #000000">&lt;&lt;</span>
								<span style="COLOR: #000000"> </span>
								<span style="COLOR: #000000">"</span>
								<span style="COLOR: #000000">Vector&lt;void*&gt;::Hello</span>
								<span style="COLOR: #000000">"</span>
								<span style="COLOR: #000000"> </span>
								<span style="COLOR: #000000">&lt;&lt;</span>
								<span style="COLOR: #000000"> std::endl;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />    }</span>
						</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span>
				</span>
				<span style="COLOR: #000000">;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /></span>
				<span style="COLOR: #0000ff">int</span>
				<span style="COLOR: #000000"> _tmain(</span>
				<span style="COLOR: #0000ff">int</span>
				<span style="COLOR: #000000"> argc, _TCHAR</span>
				<span style="COLOR: #000000">*</span>
				<span style="COLOR: #000000"> argv[])<br /><img id="Codehighlighter1_341_441_Open_Image" onclick="this.style.display='none'; Codehighlighter1_341_441_Open_Text.style.display='none'; Codehighlighter1_341_441_Closed_Image.style.display='inline'; Codehighlighter1_341_441_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_341_441_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_341_441_Closed_Text.style.display='none'; Codehighlighter1_341_441_Open_Image.style.display='inline'; Codehighlighter1_341_441_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align="top" /></span>
				<span id="Codehighlighter1_341_441_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">
						<img src="http://www.cppblog.com/images/dot.gif" />
				</span>
				<span id="Codehighlighter1_341_441_Open_Text">
						<span style="COLOR: #000000">{<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    Vector</span>
						<span style="COLOR: #000000">&lt;</span>
						<span style="COLOR: #0000ff">int</span>
						<span style="COLOR: #000000">*&gt;</span>
						<span style="COLOR: #000000">    pIntVec;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    pIntVec.Say();<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    Vector</span>
						<span style="COLOR: #000000">&lt;</span>
						<span style="COLOR: #0000ff">double</span>
						<span style="COLOR: #000000">*&gt;</span>
						<span style="COLOR: #000000">    pDoubleVec;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    pDoubleVec.Say();<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    </span>
						<span style="COLOR: #0000ff">return</span>
						<span style="COLOR: #000000"> </span>
						<span style="COLOR: #000000">0</span>
						<span style="COLOR: #000000">;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span>
				</span>
		</div>
		<p>
				<br />输出:<br />Vector&lt;int *&gt;::Hello<br />Vector&lt;double *&gt;::Hello<br />从这里,我们可以看出程序在运行的过程中生产了两分Vector的代码(int*和double*),尽管这里有特例化,然而类型不匹配,编译器在编译过程中无法定位到特例化版本.如果这个Vector被滥用的化,我想即使是一个中等规模的程序也可能耗费成兆字节的代码控件.</p>
		<p>我们必须寻找一种中间桥梁使编译器在编译过程中定位到void*的特例化版本.按照模板选择策略,编译器总是选择最特例化的模板,我们可以通过一个中间的模板联系起上面两个版本的模板.下面看一段代码:<br /></p>
		<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee">
				<img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />
				<span style="COLOR: #000000">template</span>
				<span style="COLOR: #000000">&lt;</span>
				<span style="COLOR: #000000">typename T</span>
				<span style="COLOR: #000000">&gt;</span>
				<span style="COLOR: #000000">
						<br />
						<img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />
				</span>
				<span style="COLOR: #0000ff">class</span>
				<span style="COLOR: #000000"> Vector<br /><img id="Codehighlighter1_34_115_Open_Image" onclick="this.style.display='none'; Codehighlighter1_34_115_Open_Text.style.display='none'; Codehighlighter1_34_115_Closed_Image.style.display='inline'; Codehighlighter1_34_115_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_34_115_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_34_115_Closed_Text.style.display='none'; Codehighlighter1_34_115_Open_Image.style.display='inline'; Codehighlighter1_34_115_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align="top" /></span>
				<span id="Codehighlighter1_34_115_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">
						<img src="http://www.cppblog.com/images/dot.gif" />
				</span>
				<span id="Codehighlighter1_34_115_Open_Text">
						<span style="COLOR: #000000">{<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" /></span>
						<span style="COLOR: #0000ff">public</span>
						<span style="COLOR: #000000">:<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    </span>
						<span style="COLOR: #0000ff">virtual</span>
						<span style="COLOR: #000000"> </span>
						<span style="COLOR: #0000ff">void</span>
						<span style="COLOR: #000000"> Say()<br /><img id="Codehighlighter1_65_113_Open_Image" onclick="this.style.display='none'; Codehighlighter1_65_113_Open_Text.style.display='none'; Codehighlighter1_65_113_Closed_Image.style.display='inline'; Codehighlighter1_65_113_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_65_113_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_65_113_Closed_Text.style.display='none'; Codehighlighter1_65_113_Open_Image.style.display='inline'; Codehighlighter1_65_113_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />    </span>
						<span id="Codehighlighter1_65_113_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">
								<img src="http://www.cppblog.com/images/dot.gif" />
						</span>
						<span id="Codehighlighter1_65_113_Open_Text">
								<span style="COLOR: #000000">{<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />        std::cout </span>
								<span style="COLOR: #000000">&lt;&lt;</span>
								<span style="COLOR: #000000"> </span>
								<span style="COLOR: #000000">"</span>
								<span style="COLOR: #000000">Vector::Hello</span>
								<span style="COLOR: #000000">"</span>
								<span style="COLOR: #000000"> </span>
								<span style="COLOR: #000000">&lt;&lt;</span>
								<span style="COLOR: #000000"> std::endl;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />    }</span>
						</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span>
				</span>
				<span style="COLOR: #000000">;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /></span>
				<span style="COLOR: #008000">//</span>
				<span style="COLOR: #008000"> 特例化</span>
				<span style="COLOR: #008000">
						<br />
						<img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />
				</span>
				<span style="COLOR: #000000">template</span>
				<span style="COLOR: #000000">&lt;&gt;</span>
				<span style="COLOR: #000000">
						<br />
						<img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />
				</span>
				<span style="COLOR: #0000ff">class</span>
				<span style="COLOR: #000000">  Vector</span>
				<span style="COLOR: #000000">&lt;</span>
				<span style="COLOR: #0000ff">void</span>
				<span style="COLOR: #000000">*&gt;</span>
				<span style="COLOR: #000000">
						<br />
						<img id="Codehighlighter1_158_246_Open_Image" onclick="this.style.display='none'; Codehighlighter1_158_246_Open_Text.style.display='none'; Codehighlighter1_158_246_Closed_Image.style.display='inline'; Codehighlighter1_158_246_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" />
						<img id="Codehighlighter1_158_246_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_158_246_Closed_Text.style.display='none'; Codehighlighter1_158_246_Open_Image.style.display='inline'; Codehighlighter1_158_246_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align="top" />
				</span>
				<span id="Codehighlighter1_158_246_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">
						<img src="http://www.cppblog.com/images/dot.gif" />
				</span>
				<span id="Codehighlighter1_158_246_Open_Text">
						<span style="COLOR: #000000">{<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" /></span>
						<span style="COLOR: #0000ff">public</span>
						<span style="COLOR: #000000">:<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    </span>
						<span style="COLOR: #0000ff">virtual</span>
						<span style="COLOR: #000000"> </span>
						<span style="COLOR: #0000ff">void</span>
						<span style="COLOR: #000000"> Say()<br /><img id="Codehighlighter1_189_244_Open_Image" onclick="this.style.display='none'; Codehighlighter1_189_244_Open_Text.style.display='none'; Codehighlighter1_189_244_Closed_Image.style.display='inline'; Codehighlighter1_189_244_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_189_244_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_189_244_Closed_Text.style.display='none'; Codehighlighter1_189_244_Open_Image.style.display='inline'; Codehighlighter1_189_244_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />    </span>
						<span id="Codehighlighter1_189_244_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">
								<img src="http://www.cppblog.com/images/dot.gif" />
						</span>
						<span id="Codehighlighter1_189_244_Open_Text">
								<span style="COLOR: #000000">{<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />        std::cout </span>
								<span style="COLOR: #000000">&lt;&lt;</span>
								<span style="COLOR: #000000"> </span>
								<span style="COLOR: #000000">"</span>
								<span style="COLOR: #000000">Vector&lt;void*&gt;::Hello</span>
								<span style="COLOR: #000000">"</span>
								<span style="COLOR: #000000"> </span>
								<span style="COLOR: #000000">&lt;&lt;</span>
								<span style="COLOR: #000000"> std::endl;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />    }</span>
						</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span>
				</span>
				<span style="COLOR: #000000">;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /></span>
				<span style="COLOR: #008000">//</span>
				<span style="COLOR: #008000"> 特例化</span>
				<span style="COLOR: #008000">
						<br />
						<img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />
				</span>
				<span style="COLOR: #000000">template</span>
				<span style="COLOR: #000000">&lt;</span>
				<span style="COLOR: #000000">typename T</span>
				<span style="COLOR: #000000">&gt;</span>
				<span style="COLOR: #000000">
						<br />
						<img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />
				</span>
				<span style="COLOR: #0000ff">class</span>
				<span style="COLOR: #000000"> Vector</span>
				<span style="COLOR: #000000">&lt;</span>
				<span style="COLOR: #000000">T</span>
				<span style="COLOR: #000000">*&gt;</span>
				<span style="COLOR: #000000"> : </span>
				<span style="COLOR: #0000ff">public</span>
				<span style="COLOR: #000000"> Vector</span>
				<span style="COLOR: #000000">&lt;</span>
				<span style="COLOR: #0000ff">void</span>
				<span style="COLOR: #000000">*&gt;</span>
				<span style="COLOR: #000000">
						<br />
						<img id="Codehighlighter1_318_320_Open_Image" onclick="this.style.display='none'; Codehighlighter1_318_320_Open_Text.style.display='none'; Codehighlighter1_318_320_Closed_Image.style.display='inline'; Codehighlighter1_318_320_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" />
						<img id="Codehighlighter1_318_320_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_318_320_Closed_Text.style.display='none'; Codehighlighter1_318_320_Open_Image.style.display='inline'; Codehighlighter1_318_320_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align="top" />
				</span>
				<span id="Codehighlighter1_318_320_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">
						<img src="http://www.cppblog.com/images/dot.gif" />
				</span>
				<span id="Codehighlighter1_318_320_Open_Text">
						<span style="COLOR: #000000">{<br /><img src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span>
				</span>
				<span style="COLOR: #000000">;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /></span>
				<span style="COLOR: #0000ff">int</span>
				<span style="COLOR: #000000"> _tmain(</span>
				<span style="COLOR: #0000ff">int</span>
				<span style="COLOR: #000000"> argc, _TCHAR</span>
				<span style="COLOR: #000000">*</span>
				<span style="COLOR: #000000"> argv[])<br /><img id="Codehighlighter1_361_461_Open_Image" onclick="this.style.display='none'; Codehighlighter1_361_461_Open_Text.style.display='none'; Codehighlighter1_361_461_Closed_Image.style.display='inline'; Codehighlighter1_361_461_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_361_461_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_361_461_Closed_Text.style.display='none'; Codehighlighter1_361_461_Open_Image.style.display='inline'; Codehighlighter1_361_461_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align="top" /></span>
				<span id="Codehighlighter1_361_461_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">
						<img src="http://www.cppblog.com/images/dot.gif" />
				</span>
				<span id="Codehighlighter1_361_461_Open_Text">
						<span style="COLOR: #000000">{<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    Vector</span>
						<span style="COLOR: #000000">&lt;</span>
						<span style="COLOR: #0000ff">int</span>
						<span style="COLOR: #000000">*&gt;</span>
						<span style="COLOR: #000000">    pIntVec;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    pIntVec.Say();<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    Vector</span>
						<span style="COLOR: #000000">&lt;</span>
						<span style="COLOR: #0000ff">double</span>
						<span style="COLOR: #000000">*&gt;</span>
						<span style="COLOR: #000000">    pDoubleVec;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    pDoubleVec.Say();<br /><img src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    </span>
						<span style="COLOR: #0000ff">return</span>
						<span style="COLOR: #000000"> </span>
						<span style="COLOR: #000000">0</span>
						<span style="COLOR: #000000">;<br /><img src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span>
				</span>
		</div>
		<p>
				<br />输出:<br />Vector&lt;void*&gt;::Hello<br />Vector&lt;void*&gt;::Hello<br />从这里,我们可以看出程序在运行过程中全部使用Vector&lt;void*&gt;的版本.class Vector&lt;T*&gt;模板便是关键的环节.编译器在编译过程中,由于class Vector&lt;T*&gt;比class Vector更特例化,所以遇到Vector&lt;int*&gt;和Vector&lt;double*&gt;时都选择class Vector&lt;T*&gt;,而class Vector&lt;T*&gt;继承Vector&lt;void*&gt;,一个更加特例化版本,所以编译器不再产生新的模板而采用Vector&lt;void*&gt;这个最特例化版本,这样所有指针模板都归结到Vector&lt;void*&gt;,而class Vector&lt;T*&gt;为用户提供了一个精美而且安全的界面,而Vector&lt;void*&gt;作为底层实现细节被隐藏.</p>
		<p>以上代码在VC 7.1(VS2003)中编译通过,由于VC6对模板支持不好,所以模板的高级用法一般不要在VC6中使用. <br /><a href="/files/wlwlxj/template.rar">下载演示代码</a></p>
<img src ="http://www.cppblog.com/wlwlxj/aggbug/4659.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/wlwlxj/" target="_blank">万连文</a> 2006-03-27 18:54 <a href="http://www.cppblog.com/wlwlxj/archive/2006/03/27/4659.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>