⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 index.html

📁 C程序员手册(英文)
💻 HTML
📖 第 1 页 / 共 3 页
字号:
<tt>int main()</tt>
<tt>{</tt>
<tt>  using namespace excelSoftCompany;</tt>
<tt>  string s; //referring to class excelSoftCompany::string</tt>
<tt>  std::string standardstr; //now instantiate an ANSI string</tt>
<tt>  return 0;</tt>
<tt>}</tt>
</pre>
<h3> <a name="Heading7">Namespaces Can Be Extended </a></h3>
<p>The C++ standardization committee was well aware of the fact that related declarations 
  can span across several translation units. Therefore, a namespace can be defined 
  in parts. For example</p>
<pre>
<tt>  //file proj_const.h</tt>
<tt>namespace MyProj </tt>
<tt>{</tt>
<tt>   enum NetProtocols</tt>
<tt>  {</tt>
<tt>      TCP_IP,</tt>
<tt>      HTTP,</tt>
<tt>      UDP</tt>
<tt>  };  // enum</tt>
<tt>}</tt>
<tt>  //file proj_classes.h</tt>
<tt>namespace MyProj</tt>
<tt>{ // extending MyProj namespace</tt>
<tt>   class RealTimeEncoder{ public: NetProtocols detect();  };</tt>
<tt>   class NetworkLink {}; //global</tt>
<tt>   class UserInterface {};</tt>
<tt>}</tt>
</pre>
<p>In a separate file, the same namespace can be extended with additional declarations.</p>
<p>The complete namespace <tt>MyProj</tt> can be extracted from both files as 
  follows:</p>
<pre>
<tt>  //file app.cpp</tt>
<tt>#include "proj_const.h"</tt>
<tt>#include "proj_classes.h"</tt>
<tt>int main() </tt>
<tt>{</tt>
<tt>  using namespace MyProj;</tt>
<tt>  RealTimeEncoder encoder;</tt>
<tt>  NetProtocols protocol = encoder.detect();</tt>
<tt>  return 0;</tt>
<tt>} </tt>
</pre>
<h3> <a name="Heading8">Namespace Aliases</a></h3>
<p>As you have observed, choosing a short name for a namespace can eventually 
  lead to a name clash. However, very long namespaces are not easy to use. For 
  this purpose,<i> </i>a <i>namespace alias</i> can be used. The following example 
  defines the alias <tt>ESC</tt> for the unwieldy <tt>Excel_Software_Company</tt> 
  namespace. Namespace aliases have other useful purposes, as you will see soon.</p>
<pre>
<tt>//file decl.h</tt>
<tt>namespace Excel_Software_Company </tt>
<tt>{</tt>
<tt>  class Date {/*..*/};</tt>
<tt>  class Time {/*..*/};</tt>
<tt>}</tt>
<tt>//file calendar.cpp</tt>
<tt>#include "decl.h"</tt>
<tt>int main()</tt>
<tt>{</tt>
<tt>  namespace ESC = Excel_Software_Company; //ESC is an alias for </tt>
<tt>                                          // Excel_Software_Company</tt>
<tt>  ESC::Date date;</tt>
<tt>  ESC::Time time;</tt>
<tt>  return 0;</tt>
<tt>}</tt>
</pre>
<h3> <a name="Heading9">Koenig Lookup</a></h3>
<p>Andrew Koenig, one of the creators of C++, devised an algorithm for resolving 
  namespace members' lookup. This algorithm, also called <i>argument dependent 
  lookup</i>, is used in all standard-compliant compilers to handle cases such 
  as the following:</p>
<blockquote>
  <hr>
  <strong>CAUTION: </strong> Please note that some existing compilers do not yet 
  fully support Koenig lookup. Consequently, the following programs -- which rely 
  on Koenig lookup -- might not compile under compilers that are not fully compliant 
  to the ANSI/ISO standard in this respect. 
  <hr>
</blockquote>
<pre>
<tt>namespace MINE</tt>
<tt>{</tt>
<tt>  class C {};</tt>
<tt>  void func;</tt>
<tt>}</tt>
<tt>MINE::C c; // global object of type MINE::C</tt>
<tt>int main()</tt>
<tt>{</tt>
<tt>  func( c ); // OK, MINE::f called</tt>
<tt>  return 0;</tt>
<tt>}</tt>
</pre>
<p>Neither a <tt>using</tt> declaration nor a <tt>using</tt> directive exists 
  in the program. Still, the compiler did the right thing -- it correctly identified 
  the unqualified name <tt>func</tt> as the function declared in namespace <tt>MINE</tt> 
  by applying Koenig lookup. </p>
<p>Koenig lookup instructs the compiler to look not just at the usual places, 
  such as the local scope, but also at the namespace that contains the argument's 
  type. Therefore, in the following source line, the compiler detects that the 
  object <tt>c</tt>, which is the argument of the function <tt>func()</tt>, belongs 
  to namespace <tt>MINE</tt>. Consequently, the compiler looks at namespace <tt>MINE</tt> 
  to locate the declaration of <tt>func()</tt>, "guessing" the programmer's intent:</p>
<pre>
<tt>func( c ); // OK, MINE::f called</tt>
</pre>
<p>Without Koenig lookup, namespaces impose an unacceptable tedium on the programmer, 
  who has to either repeatedly specify the fully qualified names or use numerous 
  <tt>using</tt> declarations. To push the argument in favor of Koenig lookup 
  even further, consider the following example:</p>
<pre>
<tt>#include&lt;iostream&gt;</tt>
<tt>using std::cout;</tt>
<tt>int main()</tt>
<tt>{</tt>
<tt>  cout&lt;&lt;"hello";   //OK, operator &lt;&lt; is brought into scope by Koenig lookup</tt>
<tt>  return 0;</tt>
<tt>}</tt>
</pre>
<p>The <tt>using</tt> declaration injects <tt>std::cout</tt> into the scope of 
  <tt>main()</tt>, thereby enabling the programmer to use the nonqualified name 
  <tt>cout</tt>. However, the overloaded <tt>&lt;&lt;</tt> operator, as you might 
  recall, is not a member of <tt>std::cout</tt>. It is a friend function that 
  is defined in namespace <tt>std</tt>, and which takes a <tt>std::ostream</tt> 
  object as its argument. Without Koenig lookup, the programmer has to write something 
  similar to the following:</p>
<pre>
<tt>std::operator&lt;&lt;(cout, "hello");</tt>
</pre>
<p>Alternatively, the programmer can provide a <tt>using namespace std;</tt> directive. 
  None of these options are desirable, however, because they clutter up code and 
  can become a source of confusion and errors. (<tt>using</tt> directives are 
  the least favorable form for rendering names visible in the current scope because 
  they make all the members of a namespace visible indiscriminately). Fortunately, 
  Koenig lookup "does the right thing" and saves you from this tedium in an elegant 
  way.</p>
<p>Koenig lookup is applied automatically. No special directives or configuration 
  switches are required to activate it, nor is there any way to turn it off. This 
  fact has to be kept in mind because it can have surprising results in some circumstances. 
  For example</p>
<pre>
<tt>namespace NS1</tt>
<tt>{</tt>
<tt>  class B{};</tt>
<tt>  void f;</tt>
<tt>};</tt>
<tt>void f(NS1::B); </tt>
<tt>int main()</tt>
<tt>{</tt>
<tt>  NS1::B b;</tt>
<tt>  f;  // ambiguous; NS1::f() or f(NS1::B)?</tt>
<tt>  return 0;</tt>
<tt>}</tt>
</pre>
<p>A Standard-compliant compiler should issue an error on ambiguity between <tt>NS1::f(NS1::B)</tt> 
  and <tt>f(NS1::B)</tt>. However, noncompliant compilers do not complain about 
  the ambiguous call; they simply pick one of the versions of <tt>f()</tt>. This, 
  however, might not be the version that the programmer intended. Furthermore, 
  the problem might arise only at a later stage of the development, when additional 
  versions of <tt>f()</tt> are added to the project -- which can stymie the compiler's 
  lookup algorithm. This ambiguity is not confined to global names. It might also 
  appear when two namespaces relate to one another -- for instance, if a namespace 
  declares classes that are used as parameters of a class member function that 
  is declared in a different namespace.</p>
<h3> <a name="Heading10">Namespaces in Practice</a></h3>
<p>The conclusion that can be drawn from the previous examples is that namespaces, 
  like other language features, must be used judiciously. For small programs that 
  contain only a handful of classes and a few source files, namespaces are not 
  necessary. In most cases, such programs are coded and maintained by a single 
  programmer, and they use a limited number of components. The likelihood of name 
  clashes in this case is rather small. If name clashes still occur, it is always 
  possible to rename the existing classes and functions, or simply to add namespace 
  later.</p>
<p>On the other hand, large-scale projects -- as was stated previously -- are 
  more susceptible to name clashes; therefore, they need to use namespaces systematically. 
  It is not unusual to find projects on which hundreds of programmers on a dozen 
  or so development teams are working together. The development of Microsoft Visual 
  C++ 6.0, for example, lasted 18 months, and more than 1000 people were involved 
  in the development process. Managing such a huge project requires well documented 
  coding policies -- and namespaces are one of the tools in the arsenal.</p>
<h2> <a name="Heading11">Namespace Utilization Policy in Large-Scale Projects</a></h2>
<p>To see how namespaces can be used in configuration management, imagine an online 
  transaction processing system of an imaginary international credit card company, 
  Unicard. The project comprises several development teams. One of them, the database 
  administration team, is responsible for the creation and maintenance of the 
  database tables, indexes, and access authorizations. The database team also 
  has to provide the access routines and data objects that retrieve and manipulate 
  the data in the database. A second team is responsible for the graphical user 
  interface. A third team deals with the international online requests that are 
  initiated by the cinemas, restaurants, shops, and so on where tourists pay with 
  their international Unicard. Every purchase of a cinema ticket, piece of jewelry, 
  or art book has to be confirmed by Unicard before the card owner is charged. 
  The confirmation process involves checking for the validity of the card, its 
  expiration date, and the card owner's balance. A similar confirmation procedure 
  is required for domestic purchases. However, international confirmation requests 
  are transmitted via satellite, whereas domestic confirmations are usually done 
  on the telephone. </p>
<p>In software projects, code reuse is paramount. Because the same business logic 
  is used for both domestic and international confirmations, the same database 
  access objects need to be used to retrieve the relevant information and perform 
  the necessary computations. Still, an international confirmation also involves 
  a sophisticated communication stack that receives the request that is transmitted 
  via satellite, decrypts it, and returns an encrypted response to the sender. 
  A typical implementation of satellite-based confirmation application can be 
  achieved by means of combining the database access objects with the necessary 
  communication objects that encapsulate protocols, communication layers, priority 
  management, message queuing, encryption, and decryption. It is not difficult 
  to imagine a name conflict resulting from the simultaneous use of the communication 
  components and the database access objects. </p>
<p>For example, two objects -- one encapsulating a database connection and the 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -