﻿<?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++博客-yycmmc-随笔分类-Syntax</title><link>http://www.cppblog.com/yycmmc/category/19444.html</link><description /><language>zh-cn</language><lastBuildDate>Mon, 04 Jun 2012 03:16:19 GMT</lastBuildDate><pubDate>Mon, 04 Jun 2012 03:16:19 GMT</pubDate><ttl>60</ttl><item><title>超前引用与命名空间</title><link>http://www.cppblog.com/yycmmc/archive/2012/06/04/177427.html</link><dc:creator>yycmmc</dc:creator><author>yycmmc</author><pubDate>Mon, 04 Jun 2012 02:11:00 GMT</pubDate><guid>http://www.cppblog.com/yycmmc/archive/2012/06/04/177427.html</guid><wfw:comment>http://www.cppblog.com/yycmmc/comments/177427.html</wfw:comment><comments>http://www.cppblog.com/yycmmc/archive/2012/06/04/177427.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/yycmmc/comments/commentRss/177427.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/yycmmc/services/trackbacks/177427.html</trackback:ping><description><![CDATA[&#160; &#160; 一般情况下，类型要在使用前定义，但是在一些特殊情况下，这种要求无法满足，例如两个类相互包含， 即两个类互相使用对方提供的方法。 更一般的情况，类A和类B需要彼此互相引用，这样必然有一个类会先被定义，而另外一个类后被定义，这样在先被定义的类引用后被定义的类的时候，就导致了所谓的超前引用。<br /><br />&#160; &#160; 使用命名空间的目的是对标识符的名称进行本地化，以避免命名冲突。在C++中，变量、函数和类都是大量存在的。如果没有命名空间，这些变量、函数、类的名称将都存在于全局命名空间中，会导致很多冲突。比如，如果我们在自己的程序中定义了一个函数toupper()，这将重写标准库中的toupper()函数，这是因为这两个函数都是位于全局命名空间中的。命名冲突还会发生在一个程序中使用两个或者更多的第三方库的情况中。此时，很有可能，其中一个库中的名称和另外一个库中的名称是相同的，这样就冲突了。这种情况会经常发生在类的名称上。比如，我们在自己的程序中定义了一个Stack类，而我们程序中使用的某个库中也可能定义了一个同名的类，此时名称就冲突了。namespace关键字的出现就是针对这种问题的。由于这种机制对于声明于其中的名称都进行了本地化，就使得相同的名称可以在不同的上下文中使用，而不会引起名称的冲突。或许命名空间最大的受益者就是C++中的标准库了。在命名空间出现之前，整个C++库都是定义在全局命名空间中的（这当然也是唯一的命名空间）。引入命名空间后，C++库就被定义到自己的名称空间中了，称之为std。这样就减少了名称冲突的可能性。我们也可以在自己的程序中创建自己的命名空间，这样可以对我们认为可能导致冲突的名称进行本地化。这点在我们创建类或者是函数库的时候是特别重要的。<br /><br />新建类A、类B分别放在NA、NB命名空间下：<br /><div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 4px; background-color: #eeeeee; padding-left: 4px; width: 98%; padding-right: 5px; font-size: 13px; word-break: break-all; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 4px"><span style="color: #008000">//</span><span style="color: #008000">A.h</span><span style="color: #000000"><br /></span><span style="color: #333399">#pragma once<br /><br /></span><span style="color: #0000ff">namespace</span><span style="color: #000000">&#160;NA{<br /><br /></span><span style="color: #0000ff">class</span><span style="color: #000000">&#160;A{<br /><br /></span><span style="color: #0000ff">private</span><span style="color: #000000">:<br />&#160;&#160;&#160;&#160;B</span><span style="color: #000000">*</span><span style="color: #000000">&#160;m_b;<br /><br /></span><span style="color: #0000ff">public</span><span style="color: #000000">:<br />&#160;&#160;&#160;&#160;A(</span><span style="color: #0000ff">void</span><span style="color: #000000">);<br />&#160;&#160;&#160;&#160;</span><span style="color: #000000">~</span><span style="color: #000000">A(</span><span style="color: #0000ff">void</span><span style="color: #000000">);<br />&#160;&#160;&#160;&#160;</span><span style="color: #0000ff">void</span><span style="color: #000000">&#160;A_DoSomething(){<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</span><span style="color: #0000ff">this</span><span style="color: #000000">-&gt;</span><span style="color: #000000">m_b</span><span style="color: #000000">-&gt;</span><span style="color: #000000">B_DoSomething();<br />&#160;&#160;&#160;&#160;}<br />};<br /><br />}</span></div><br /><p>&#160;</p><div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 4px; background-color: #eeeeee; padding-left: 4px; width: 98%; padding-right: 5px; font-size: 13px; word-break: break-all; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 4px"><span style="color: #008000">//</span><span style="color: #008000">B.h</span><span style="color: #008000"><br /></span><span style="color: #333399">#pragma&#160;once<br /><br /></span><span style="color: #0000ff">namespace</span><span style="color: #000000">&#160;NB{<br /></span><span style="color: #0000ff">class</span><span style="color: #000000">&#160;B<br />{<br /></span><span style="color: #0000ff">public</span><span style="color: #000000">:<br />&#160;&#160;&#160;&#160;B(</span><span style="color: #0000ff">void</span><span style="color: #000000">){<br />&#160;&#160;&#160;&#160;}<br />&#160;&#160;&#160;&#160;</span><span style="color: #000000">~</span><span style="color: #000000">B(</span><span style="color: #0000ff">void</span><span style="color: #000000">){<br />&#160;&#160;&#160;&#160;}<br />&#160;&#160;&#160;&#160;</span><span style="color: #0000ff">void</span><span style="color: #000000">&#160;B_DoSomething(){<br /><br />&#160;&#160;&#160;&#160;}<br />};<br /><br />}</span></div><br /><p>&#160;</p><p>&#160; &#160;因为在类A&#160;中引用了B类，所以要在类A中包含B的头文件，并且声明类B，对类A作如下修改：</p><p><br /></p><p>&#160;</p><div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 4px; background-color: #eeeeee; padding-left: 4px; width: 98%; padding-right: 5px; font-size: 13px; word-break: break-all; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 4px"><span style="color: #333399">#pragma&#160;once<br /><br /></span><span style="color: #333399">#include&#160;</span><span style="color: #333399">"</span><span style="color: #333399">B.h</span><span style="color: #333399">"</span><span style="color: #000000">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</span><span style="color: #008000">//</span><span style="color: #008000">STEP&#160;1&#160;:&#160;包含要用到类的头文件</span><span style="color: #008000"><br /></span><span style="color: #000000"><br /></span><span style="color: #0000ff">class</span><span style="color: #000000"> B; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160;</span><span style="color: #008000">//</span><span style="color: #008000">STEP 2 : 声明</span><span style="color: #008000">要超前引用的</span><span style="color: #008000">类<br /><br /></span><span style="color: #0000ff">namespace</span><span style="color: #000000">&#160;NA{<br /><br /></span><span style="color: #0000ff">class</span><span style="color: #000000">&#160;A{<br /><br /></span><span style="color: #0000ff">private</span><span style="color: #000000">:<br />&#160;&#160;&#160;&#160;B</span><span style="color: #000000">*</span><span style="color: #000000">&#160;m_b;<br /><br /></span><span style="color: #0000ff">public</span><span style="color: #000000">:<br />&#160;&#160;&#160;&#160;A(</span><span style="color: #0000ff">void</span><span style="color: #000000">);<br />&#160;&#160;&#160;&#160;</span><span style="color: #000000">~</span><span style="color: #000000">A(</span><span style="color: #0000ff">void</span><span style="color: #000000">);<br />&#160;&#160;&#160;&#160;</span><span style="color: #0000ff">void</span><span style="color: #000000">&#160;A_DoSomething(){<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</span><span style="color: #0000ff">this</span><span style="color: #000000">-&gt;</span><span style="color: #000000">m_b</span><span style="color: #000000">-&gt;</span><span style="color: #000000">B_DoSomething();<br />&#160;&#160;&#160;&#160;}<br />};<br /><br />}</span></div><p>&#160;</p><p><br /></p><p>此时，满怀信心的编译一下，一定会令你失望！提示编译错误，如图1(VS2010中)：</p><p><img border="0" alt="" src="http://www.cppblog.com/images/cppblog_com/yycmmc/namespace_error_1.png" width="270" height="253" /></p><p>&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; 图1&#160;</p><p><img border="0" alt="" src="http://www.cppblog.com/images/cppblog_com/yycmmc/namespace_error_2.png" width="466" height="101" /></p><p>&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; 图2&#160;</p><p>错误指出，在该类B下找不到要用到的方法B_DoSomething()，尝试将类B的声明移动到命名空间NA中，发现一个奇怪的现象，如图3<img border="0" alt="" src="http://www.cppblog.com/images/cppblog_com/yycmmc/namespace_error_3.png" width="485" height="324" /></p><p>&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; 图3</p><p>编译器认为，类B声明在命名空间NA下，由此分析，如果类B的声明在命名空间NA之外的话，编译器就认为类B的声明在全局命名空间中，而在全局命名空间下是不存在类B的，找不到B的方法也就不足为奇了，为此继续修改类A，将类B的声明限定在其所在命名空间NB下，如下所示：</p><p>&#160;</p><div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 4px; background-color: #eeeeee; padding-left: 4px; width: 98%; padding-right: 5px; font-size: 13px; word-break: break-all; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 4px"><span style="color: #0000ff">#pragma&#160;once<br /><br /></span><span style="color: #0000ff">#include&#160;</span><span style="color: #0000ff">"</span><span style="color: #0000ff">B.h</span><span style="color: #0000ff">"</span><span style="color: #000000">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</span><span style="color: #008000">//</span><span style="color: #008000">STEP&#160;1&#160;:&#160;包含要用到类的头文件<br /><br /></span><span style="color: #008000">//</span><span style="color: #0000ff">class</span><span style="color: #000000">&#160;B;&#160;&#160;&#160;</span><span style="color: #008000">&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160;</span><span style="color: #008000">//</span><span style="color: #008000">ERROR&#160;:&#160;将类B声明在了全局命名空间下</span><span style="color: #008000"><br /></span><span style="color: #000000"><br /></span><span style="color: #0000ff">namespace</span><span style="color: #000000"> NB{ &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160;</span><span style="color: #008000"> //</span><span style="color: #008000">STEP&#160;2&#160;:&#160;将该类声明在其所在命名空间下</span><span style="color: #008000"><br /></span><span style="color: #000000">&#160;&#160;&#160;&#160;</span><span style="color: #0000ff">class</span><span style="color: #000000"> B; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; </span><span style="color: #008000">//</span><span style="color: #008000">OK&#160;:&#160;将类B声明在了NB命名空间下</span><span style="color: #008000"><br /></span><span style="color: #000000">}<br /><br /></span><span style="color: #0000ff">namespace</span><span style="color: #000000">&#160;NA{<br /><br /></span><span style="color: #0000ff">class</span><span style="color: #000000">&#160;A{<br /><br /></span><span style="color: #0000ff">private</span><span style="color: #000000">:<br />&#160;&#160;&#160;&#160;B</span><span style="color: #000000">*</span><span style="color: #000000">&#160;m_b;<br /><br /></span><span style="color: #0000ff">public</span><span style="color: #000000">:<br />&#160;&#160;&#160;&#160;A(</span><span style="color: #0000ff">void</span><span style="color: #000000">);<br />&#160;&#160;&#160;&#160;</span><span style="color: #000000">~</span><span style="color: #000000">A(</span><span style="color: #0000ff">void</span><span style="color: #000000">);<br />&#160;&#160;&#160;&#160;</span><span style="color: #0000ff">void</span><span style="color: #000000">&#160;A_DoSomething(){<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</span><span style="color: #0000ff">this</span><span style="color: #000000">-&gt;</span><span style="color: #000000">m_b</span><span style="color: #000000">-&gt;</span><span style="color: #000000">B_DoSomething();<br />&#160;&#160;&#160;&#160;}<br />};<br /><br />}</span></div><p>&#160;</p><p><br /></p><p>此时，大功似乎告成，编译下，仍有错误，如图4所示：</p><p><img border="0" alt="" src="http://www.cppblog.com/images/cppblog_com/yycmmc/namespace_error_4.png" width="484" height="293" /></p><p><br /></p><p>提示找不到类B的声明，回头一想，应该声明所在的命名空间吧，于是添加 using namespace NB;&#160;重新编译，仍然出错，郁闷了，改为直接引用类名，即 using NB::B;&#160;重新编译，意外通过了编译！如下完整代码：</p><p>&#160;</p><div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 4px; background-color: #eeeeee; padding-left: 4px; width: 98%; padding-right: 5px; font-size: 13px; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 4px"><span style="color: #000000">#pragma&#160;once<br /></span><span style="color: #008000">//</span><span style="color: #008000">超前引用不同命名空间下的不同类、变量、方法时，要限定命名空间</span><span style="color: #008000"><br /></span><span style="color: #000000"><br /></span><span style="color: #0000ff">#include&#160;</span><span style="color: #0000ff">"</span><span style="color: #0000ff">B.h</span><span style="color: #0000ff">"</span><span style="color: #000000">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</span><span style="color: #008000"> &#160; &#160; //</span><span style="color: #008000">STEP&#160;1&#160;:&#160;包含要用到类的头文件<br /><br /></span><span style="color: #008000">//</span><span style="color: #008000">class B; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160;</span><span style="color: #008000">//</span><span style="color: #008000">ERROR&#160;:&#160;将类B声明在了全局命名空间下</span><span style="color: #008000"><br /></span><span style="color: #0000ff">namespace</span><span style="color: #000000"> NB{ &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160;</span><span style="color: #008000">//</span><span style="color: #008000">STEP&#160;2&#160;:&#160;将该类声明在其所在命名空间下</span><span style="color: #008000"><br /></span><span style="color: #000000">&#160;&#160;&#160;&#160;</span><span style="color: #0000ff">class</span><span style="color: #000000">&#160;B;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</span><span style="color: #008000">//</span><span style="color: #008000">OK&#160;:&#160;将类B声明在了NB命名空间下</span><span style="color: #008000"><br /></span><span style="color: #000000">}<br /><br /></span><span style="color: #008000">//</span><span style="color: #008000">using&#160;namespace&#160;NB;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</span><span style="color: #008000"> &#160; //</span><span style="color: #008000">ERROR！！</span><span style="color: #008000"><br /></span><span style="color: #0000ff">using</span><span style="color: #000000">&#160;&#160;NB::B;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</span><span style="color: #008000">//</span><span style="color: #008000">STEP&#160;3&#160;:&#160;直接声明使用在所在命名空间下的类</span><span style="color: #008000"><br /></span><span style="color: #000000"><br /></span><span style="color: #0000ff">namespace</span><span style="color: #000000">&#160;NA{<br /><br /></span><span style="color: #0000ff">class</span><span style="color: #000000">&#160;A{<br /><br /></span><span style="color: #0000ff">private</span><span style="color: #000000">:<br />&#160;&#160;&#160;&#160;B</span><span style="color: #000000">*</span><span style="color: #000000">&#160;m_b;<br /><br /></span><span style="color: #0000ff">public</span><span style="color: #000000">:<br />&#160;&#160;&#160;&#160;A(</span><span style="color: #0000ff">void</span><span style="color: #000000">);<br />&#160;&#160;&#160;&#160;</span><span style="color: #000000">~</span><span style="color: #000000">A(</span><span style="color: #0000ff">void</span><span style="color: #000000">);<br />&#160;&#160;&#160;&#160;</span><span style="color: #0000ff">void</span><span style="color: #000000">&#160;A_DoSomething(){<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</span><span style="color: #0000ff">this</span><span style="color: #000000">-&gt;</span><span style="color: #000000">m_b</span><span style="color: #000000">-&gt;</span><span style="color: #000000">B_DoSomething();<br />&#160;&#160;&#160;&#160;}<br />};<br /><br />}</span></div><p>&#160;</p><p><br /></p><p><br /></p><p><br /></p><p><br /></p> <img src ="http://www.cppblog.com/yycmmc/aggbug/177427.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/yycmmc/" target="_blank">yycmmc</a> 2012-06-04 10:11 <a href="http://www.cppblog.com/yycmmc/archive/2012/06/04/177427.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C++编译错误分析之－无法解析的外部符号</title><link>http://www.cppblog.com/yycmmc/archive/2012/05/30/176833.html</link><dc:creator>yycmmc</dc:creator><author>yycmmc</author><pubDate>Wed, 30 May 2012 15:04:00 GMT</pubDate><guid>http://www.cppblog.com/yycmmc/archive/2012/05/30/176833.html</guid><wfw:comment>http://www.cppblog.com/yycmmc/comments/176833.html</wfw:comment><comments>http://www.cppblog.com/yycmmc/archive/2012/05/30/176833.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/yycmmc/comments/commentRss/176833.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/yycmmc/services/trackbacks/176833.html</trackback:ping><description><![CDATA[		<p>一、如果使用了库文件：</p>
		<p>1.libname.lib 库文件未引入，可使用&#8220;#pragma comment(lib, &#8220; libname.lib&#8221;) &#8221;语句添加 lib 引用，也可在项目依赖里添加。&#160;</p>
		<p>2.某个类方法的实现部分未添加所属类标识。如， &#8220;CClassName::DoSomething(void) { //&#8230; }&#8221; 误写成了 &#8220; CClassName::DoSomething(void) {// &#8230; } &#8221;。&#160;</p>
		<p>3.项目使用的库方法未添加可导出标识 "__declspec(dllexport)",在VS IDE&#160;中，用一个宏来代替，如</p>
		<p>
		</p>
		<div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all">
				<span style="color: #008080; ">1</span>&#160;<span style="color: #000000; ">#ifdef&#160;ALIB_EXPORTS<br /></span><span style="color: #008080; ">2</span>&#160;<span style="color: #0000FF; ">#define</span><span style="color: #000000; ">&#160;ALIB&#160;_API&#160;__declspec(dllexport)</span><span style="color: #000000; "><br /></span><span style="color: #008080; ">3</span>&#160;<span style="color: #0000FF; ">#else</span><span style="color: #000000; "><br /></span><span style="color: #008080; ">4</span>&#160;<span style="color: #0000FF; ">#define</span><span style="color: #000000; ">&#160;ALIB&#160;_API&#160;__declspec(dllimport)</span><span style="color: #000000; "><br /></span><span style="color: #008080; ">5</span>&#160;<span style="color: #0000FF; ">#endif</span></div>
3.  缺少 obj 文件。在项目里添加&#8220;包含路径&#8221;：C:/curl/lib/release-dll/*.obj。 <br />
4.如果使用了模板类时，模板类的声明和定义要在一起，分离声明和定义时报错！<br />
5. 没有将项目需要的头文件、源文件都加入项目中。
 <img src ="http://www.cppblog.com/yycmmc/aggbug/176833.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/yycmmc/" target="_blank">yycmmc</a> 2012-05-30 23:04 <a href="http://www.cppblog.com/yycmmc/archive/2012/05/30/176833.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>