﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-学习、成长之路-随笔分类-C++</title><link>http://www.cppblog.com/sToa/category/11490.html</link><description /><language>zh-cn</language><lastBuildDate>Mon, 17 Aug 2009 03:32:18 GMT</lastBuildDate><pubDate>Mon, 17 Aug 2009 03:32:18 GMT</pubDate><ttl>60</ttl><item><title>在类模板的声明和定义中把.h与.cpp分离</title><link>http://www.cppblog.com/sToa/archive/2009/07/25/91125.html</link><dc:creator>sToa</dc:creator><author>sToa</author><pubDate>Sat, 25 Jul 2009 07:10:00 GMT</pubDate><guid>http://www.cppblog.com/sToa/archive/2009/07/25/91125.html</guid><wfw:comment>http://www.cppblog.com/sToa/comments/91125.html</wfw:comment><comments>http://www.cppblog.com/sToa/archive/2009/07/25/91125.html#Feedback</comments><slash:comments>5</slash:comments><wfw:commentRss>http://www.cppblog.com/sToa/comments/commentRss/91125.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/sToa/services/trackbacks/91125.html</trackback:ping><description><![CDATA[<span><strong>看了几位大吓的回复,深深地感觉到了这篇附笔中可能存在错误,于是把最初遇到此问题时的环境再模拟了一下,现在可以确认这篇附笔中的确存在问题,现在就修正一下,并对各位表示歉意.<br>6月初的一个项目中需要写一个高性能网络服务端程序,在网上找到了一份很好的代码(</strong></span><a title=请参见 href="http://www.codeproject.com/KB/IP/IOCP_how_to_cook.aspx"><strong>请参见</strong></a><span><strong>),在使用过程中发现在多个cpp文件中引入这份代码的h文件时,会出现很多重复定义错误,当时很头疼,没能很好的解决问题.<br>现总结一条:在使用类模板技术时,可在.h中实现,也可在.h和.cpp中分开实现,若用.h实现,不要在文件中加入非类模板代码,可避免重写定义错误..<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2009年7月25日23时58分58秒<br>//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////<br>// 原文如下:Posted on 2009-07-25 15:10 sToa<br>//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////</strong></span><br>1.声明部分
<div><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>//&nbsp;Tpl.h<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>#pragma&nbsp;once<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&lt;class&nbsp;T&gt;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>class&nbsp;CTpl&nbsp;&nbsp;<br><img id=Codehighlighter1_54_110_Open_Image onclick="this.style.display='none'; Codehighlighter1_54_110_Open_Text.style.display='none'; Codehighlighter1_54_110_Closed_Image.style.display='inline'; Codehighlighter1_54_110_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_54_110_Closed_Image onclick="this.style.display='none'; Codehighlighter1_54_110_Closed_Text.style.display='none'; Codehighlighter1_54_110_Open_Image.style.display='inline'; Codehighlighter1_54_110_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top><img src="http://www.cppblog.com/Images/dot.gif">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>public:<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;CTpl();<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;virtual&nbsp;~CTpl();<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;void&nbsp;Test(T&nbsp;t);<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>};<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></div>
<br>2.实现部分
<div><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>//&nbsp;Tpl.cpp<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>#include&nbsp;"Tpl.h"<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&lt;class&nbsp;T&gt;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>CTpl&lt;T&gt;::CTpl()<br><img id=Codehighlighter1_63_66_Open_Image onclick="this.style.display='none'; Codehighlighter1_63_66_Open_Text.style.display='none'; Codehighlighter1_63_66_Closed_Image.style.display='inline'; Codehighlighter1_63_66_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_63_66_Closed_Image onclick="this.style.display='none'; Codehighlighter1_63_66_Closed_Text.style.display='none'; Codehighlighter1_63_66_Open_Image.style.display='inline'; Codehighlighter1_63_66_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top><img src="http://www.cppblog.com/Images/dot.gif">{<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>}<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&lt;class&nbsp;T&gt;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>CTpl&lt;T&gt;::~CTpl()<br><img id=Codehighlighter1_104_107_Open_Image onclick="this.style.display='none'; Codehighlighter1_104_107_Open_Text.style.display='none'; Codehighlighter1_104_107_Closed_Image.style.display='inline'; Codehighlighter1_104_107_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_104_107_Closed_Image onclick="this.style.display='none'; Codehighlighter1_104_107_Closed_Text.style.display='none'; Codehighlighter1_104_107_Open_Image.style.display='inline'; Codehighlighter1_104_107_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top><img src="http://www.cppblog.com/Images/dot.gif">{<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>}<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&lt;class&nbsp;T&gt;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>void&nbsp;CTpl&lt;T&gt;::Test(T&nbsp;t)<br><img id=Codehighlighter1_152_155_Open_Image onclick="this.style.display='none'; Codehighlighter1_152_155_Open_Text.style.display='none'; Codehighlighter1_152_155_Closed_Image.style.display='inline'; Codehighlighter1_152_155_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_152_155_Closed_Image onclick="this.style.display='none'; Codehighlighter1_152_155_Closed_Text.style.display='none'; Codehighlighter1_152_155_Open_Image.style.display='inline'; Codehighlighter1_152_155_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top><img src="http://www.cppblog.com/Images/dot.gif">{<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>}</div>
3.习惯错误用法<br>
<div><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>//&nbsp;main.cpp<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>#include&nbsp;"Tpl.h"<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>int&nbsp;main()<br><img id=Codehighlighter1_41_83_Open_Image onclick="this.style.display='none'; Codehighlighter1_41_83_Open_Text.style.display='none'; Codehighlighter1_41_83_Closed_Image.style.display='inline'; Codehighlighter1_41_83_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_41_83_Closed_Image onclick="this.style.display='none'; Codehighlighter1_41_83_Closed_Text.style.display='none'; Codehighlighter1_41_83_Open_Image.style.display='inline'; Codehighlighter1_41_83_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top><img src="http://www.cppblog.com/Images/dot.gif">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;CTpl&lt;char&gt;&nbsp;ts;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;ts.Test(3);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;0;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</div>
<p>build时出现link错误<br>main.obj : error LNK2001: unresolved external symbol "public: virtual __thiscall CTpl&lt;char&gt;::~CTpl&lt;char&gt;(void)" (<a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#63;&#63;&#49;&#63;&#36;&#67;&#84;&#112;&#108;&#64;&#68;&#64;&#64;&#85;&#65;&#69;&#64;&#88;&#90;">??1?$CTpl@D@@UAE@XZ</a>)<br>main.obj : error LNK2001: unresolved external symbol "public: void __thiscall CTpl&lt;char&gt;::Test(char)" (<a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#63;&#84;&#101;&#115;&#116;&#64;&#63;&#36;&#67;&#84;&#112;&#108;&#64;&#68;&#64;&#64;&#81;&#65;&#69;&#88;&#68;&#64;&#90;">?Test@?$CTpl@D@@QAEXD@Z</a>)<br>main.obj : error LNK2001: unresolved external symbol "public: __thiscall CTpl&lt;char&gt;::CTpl&lt;char&gt;(void)" (<a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#63;&#63;&#48;&#63;&#36;&#67;&#84;&#112;&#108;&#64;&#68;&#64;&#64;&#81;&#65;&#69;&#64;&#88;&#90;">??0?$CTpl@D@@QAE@XZ</a>)<br>这组错误信息和project中不加入Tpl.cpp的错误信息一样,即没有CTpl&lt;char&gt;的实现代码<br>我们把Tpl.cpp包涵到main.cpp中,问题解决<br>4.正确用法<br></p>
<div><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>//&nbsp;main.cpp<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>#include&nbsp;"tpl.cpp"<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>int&nbsp;main()<br><img id=Codehighlighter1_42_84_Open_Image onclick="this.style.display='none'; Codehighlighter1_42_84_Open_Text.style.display='none'; Codehighlighter1_42_84_Closed_Image.style.display='inline'; Codehighlighter1_42_84_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_42_84_Closed_Image onclick="this.style.display='none'; Codehighlighter1_42_84_Closed_Text.style.display='none'; Codehighlighter1_42_84_Open_Image.style.display='inline'; Codehighlighter1_42_84_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top><img src="http://www.cppblog.com/Images/dot.gif">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;CTpl&lt;char&gt;&nbsp;ts;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;ts.Test(3);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;0;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</div>
<p>5.总结<br>1.在使用以.h,.cpp分离实现模板类时,不能像使用普通类一样只简单的包涵.h头文件,应该在使用模板类的cpp文件中引入模板类相应的cpp文件<br>2.将模板类的声明与实现都放在.h中(在多个cpp中使用不同模板参数时可能会引起重复定义的编译错误)<br><br><br><br><br></p>
<img src ="http://www.cppblog.com/sToa/aggbug/91125.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/sToa/" target="_blank">sToa</a> 2009-07-25 15:10 <a href="http://www.cppblog.com/sToa/archive/2009/07/25/91125.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>