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

📄 chapter10.html

📁 Thinking in c++ 2nd edition,c++编程思想(第2版)
💻 HTML
📖 第 1 页 / 共 5 页
字号:

<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">This produces a new namespace containing
the enclosed declarations. There are significant differences from <B>class</B>,
<B>struct</B>, <B>union</B> and <B>enum</B>,
however<A NAME="Index1763"></A><A NAME="Index1764"></A><A NAME="Index1765"></A><A NAME="Index1766"></A>:</FONT><BR></P></DIV>
<UL>
<LI><FONT FACE="Symbol">	</FONT><FONT FACE="Georgia">A namespace definition can
appear only at global scope, or nested within another
namespace.</FONT><LI><FONT FACE="Symbol">	</FONT><FONT FACE="Georgia">No
terminating semicolon is necessary after the closing brace of a namespace
definition.</FONT><LI><FONT FACE="Symbol">	</FONT><FONT FACE="Georgia">A
namespace definition can be &#8220;continued&#8221; over multiple header files
using a syntax that, for a class, would appear to be a redefinition:</FONT></UL>
<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#009900>//: C10:Header1.h</font>
#ifndef HEADER1_H
#define HEADER1_H
<font color=#0000ff>namespace</font> MyLib {
  <font color=#0000ff>extern</font> <font color=#0000ff>int</font> x;
  <font color=#0000ff>void</font> f();
  <font color=#009900>// ...</font>
} </PRE></FONT></BLOCKQUOTE>


<BLOCKQUOTE><FONT SIZE = "+1"><PRE>#endif <font color=#009900>// HEADER1_H ///:~</font>
<font color=#009900>//: C10:Header2.h</font>
#ifndef HEADER2_H
#define HEADER2_H
#include <font color=#004488>"Header1.h"</font>
<font color=#009900>// Add more names to MyLib</font>
<font color=#0000ff>namespace</font> MyLib { <font color=#009900>// NOT a redefinition!</font>
  <font color=#0000ff>extern</font> <font color=#0000ff>int</font> y;
  <font color=#0000ff>void</font> g();
  <font color=#009900>// ...</font>
} </PRE></FONT></BLOCKQUOTE>


<BLOCKQUOTE><FONT SIZE = "+1"><PRE>#endif <font color=#009900>// HEADER2_H ///:~</font>
<font color=#009900>//: C10:Continuation.cpp</font>
#include <font color=#004488>"Header2.h"</font>
<font color=#0000ff>int</font> main() {} <font color=#009900>///:~</font></PRE></FONT></BLOCKQUOTE>

<UL>
<LI><FONT FACE="Symbol">	</FONT><FONT FACE="Georgia">A namespace name can be
<I>aliased</I> to another name, so you don&#8217;t have to type an unwieldy name
created by a library vendor:</FONT></UL>
<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#009900>//: C10:BobsSuperDuperLibrary.cpp</font>
<font color=#0000ff>namespace</font> BobsSuperDuperLibrary {
  <font color=#0000ff>class</font> Widget { <font color=#009900>/* ... */</font> };
  <font color=#0000ff>class</font> Poppit { <font color=#009900>/* ... */</font> };
  <font color=#009900>// ...</font>
}
<font color=#009900>// Too much to type! I&#8217;ll alias it:</font>
<font color=#0000ff>namespace</font> Bob = BobsSuperDuperLibrary;
<font color=#0000ff>int</font> main() {} <font color=#009900>///:~</font></PRE></FONT></BLOCKQUOTE>

<UL>
<LI><FONT FACE="Symbol">	</FONT><FONT FACE="Georgia">You cannot create an
instance of a namespace as you can with a
class.</FONT></UL><A NAME="Heading305"></A><FONT FACE = "Verdana"><H4 ALIGN="LEFT">
Unnamed namespaces</H4></FONT>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Each translation unit contains an unnamed
namespace <A NAME="Index1767"></A><A NAME="Index1768"></A>that you can add to by
saying &#8220;<B>namespace</B>&#8221; without an identifier:</FONT><BR></P></DIV>

<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#009900>//: C10:UnnamedNamespaces.cpp</font>
<font color=#0000ff>namespace</font> {
  <font color=#0000ff>class</font> Arm  { <font color=#009900>/* ... */</font> };
  <font color=#0000ff>class</font> Leg  { <font color=#009900>/* ... */</font> };
  <font color=#0000ff>class</font> Head { <font color=#009900>/* ... */</font> };
  <font color=#0000ff>class</font> Robot {
    Arm arm[4];
    Leg leg[16];
    Head head[3];
    <font color=#009900>// ...</font>
  } xanthan;
  <font color=#0000ff>int</font> i, j, k;
}
<font color=#0000ff>int</font> main() {} <font color=#009900>///:~</font></PRE></FONT></BLOCKQUOTE>

<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The names in this space are automatically
available in that translation unit without qualification. It is guaranteed that
an unnamed space is unique for each translation unit. If you put local names in
an unnamed namespace, you don&#8217;t need to give them internal linkage by
making them <B>static</B>.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">C++ deprecates the use of file statics in
favor of the unnamed namespace.</FONT><BR></P></DIV>
<A NAME="Heading306"></A><FONT FACE = "Verdana"><H4 ALIGN="LEFT">
Friends</H4></FONT>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">You can <I>inject</I>
<A NAME="Index1769"></A>a <B>friend</B> <A NAME="Index1770"></A>declaration into
a namespace <A NAME="Index1771"></A>by declaring it within an enclosed
class:</FONT><BR></P></DIV>

<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#009900>//: C10:FriendInjection.cpp</font>
<font color=#0000ff>namespace</font> Me {
  <font color=#0000ff>class</font> Us {
    <font color=#009900>//...</font>
    <font color=#0000ff>friend</font> <font color=#0000ff>void</font> you();
  };
} 
<font color=#0000ff>int</font> main() {} <font color=#009900>///:~</font></PRE></FONT></BLOCKQUOTE>

<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Now the function <B>you(&#160;)</B> is a
member of the namespace <B>Me</B>.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">If you introduce a friend within a class
in the global namespace, the friend is injected
globally.</FONT><A NAME="_Toc312373947"></A><A NAME="_Toc472654921"></A><BR></P></DIV>
<A NAME="Heading307"></A><FONT FACE = "Verdana"><H3 ALIGN="LEFT">
Using a namespace</H3></FONT>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">You can refer to a name within a
namespace <A NAME="Index1772"></A>in three ways: by specifying the name using
the scope resolution operator, with a <B>using</B> directive to introduce all
names in the namespace, or with a <A NAME="Index1773"></A><B>using</B>
<A NAME="Index1774"></A><A NAME="Index1775"></A>declaration to introduce names
one at a time.</FONT><BR></P></DIV>
<A NAME="Heading308"></A><FONT FACE = "Verdana"><H4 ALIGN="LEFT">
Scope resolution</H4></FONT>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Any name in a namespace can be explicitly
specified using the
<A NAME="Index1776"></A><A NAME="Index1777"></A><A NAME="Index1778"></A>scope
resolution operator in the same way that you can refer to the names within a
class:</FONT><BR></P></DIV>

<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#009900>//: C10:ScopeResolution.cpp</font>
<font color=#0000ff>namespace</font> X {
  <font color=#0000ff>class</font> Y {
    <font color=#0000ff>static</font> <font color=#0000ff>int</font> i;
  <font color=#0000ff>public</font>:
    <font color=#0000ff>void</font> f();
  };
  <font color=#0000ff>class</font> Z;
  <font color=#0000ff>void</font> func();
}
<font color=#0000ff>int</font> X::Y::i = 9;</PRE></FONT></BLOCKQUOTE>

<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#0000ff>class</font> X::Z {
  <font color=#0000ff>int</font> u, v, w;
<font color=#0000ff>public</font>:
  Z(<font color=#0000ff>int</font> i);
  <font color=#0000ff>int</font> g();
}; </PRE></FONT></BLOCKQUOTE>

<BLOCKQUOTE><FONT SIZE = "+1"><PRE>X::Z::Z(<font color=#0000ff>int</font> i) { u = v = w = i; }
<font color=#0000ff>int</font> X::Z::g() { <font color=#0000ff>return</font> u = v = w = 0; }</PRE></FONT></BLOCKQUOTE>

<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#0000ff>void</font> X::func() {
  X::Z a(1);
  a.g();
}
<font color=#0000ff>int</font> main(){} <font color=#009900>///:~</font></PRE></FONT></BLOCKQUOTE>

<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Notice that the definition <B>X::Y::i</B>
could just as easily be referring to a data member of a class <B>Y</B> nested in
a class <B>X</B> instead of a namespace <B>X</B>.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">So far, namespaces look very much like
classes.</FONT><BR></P></DIV>
<A NAME="Heading309"></A><FONT FACE = "Verdana"><H4 ALIGN="LEFT">
The using directive</H4></FONT>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Because it can rapidly get tedious to
type the full qualification for an identifier in a namespace, the <B>using</B>
keyword allows you to import an entire namespace at once. When used in
conjunction with the <B>namespace</B> keyword this is called a
<A NAME="Index1779"></A><I>using
directive<A NAME="Index1780"></A><A NAME="Index1781"></A></I>. The <B>using</B>
directive makes names appear as if they belong to the nearest enclosing
namespace scope, so you can conveniently use the unqualified names. Consider a
simple namespace:</FONT><BR></P></DIV>

<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#009900>//: C10:NamespaceInt.h</font>
#ifndef NAMESPACEINT_H
#define NAMESPACEINT_H
<font color=#0000ff>namespace</font> Int {
  <font color=#0000ff>enum</font> sign { positive, negative };
  <font color=#0000ff>class</font> Integer {
    <font color=#0000ff>int</font> i;
    sign s;
  <font color=#0000ff>public</font>:
    Integer(<font color=#0000ff>int</font> ii = 0) 
      : i(ii),
        s(i &gt;= 0 ? positive : negative)
    {}
    sign getSign() <font color=#0000ff>const</font> { <font color=#0000ff>return</font> s; }
    <font color=#0000ff>void</font> setSign(sign sgn) { s = sgn; }
    <font color=#009900>// ...</font>
  };
} 
#endif <font color=#009900>// NAMESPACEINT_H ///:~</font></PRE></FONT></BLOCKQUOTE>

<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">One use of the <B>using </B>directive is
to bring all of the names in <B>Int</B> into another namespace, leaving those
names nested within the namespace:</FONT><BR></P></DIV>

<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#009900>//: C10:NamespaceMath.h</font>
#ifndef NAMESPACEMATH_H
#define NAMESPACEMATH_H
#include <font color=#004488>"NamespaceInt.h"</font>
<font color=#0000ff>namespace</font> Math {
  <font color=#0000ff>using</font> <font color=#0000ff>namespace</font> Int;
  Integer a, b;
  Integer divide(Integer, Integer);
  <font color=#009900>// ...</font>
} 
#endif <font color=#009900>// NAMESPACEMATH_H ///:~</font></PRE></FONT></BLOCKQUOTE>

<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">You can also declare all of the names in
<B>Int</B> inside a function, but leave those names nested within the
function:</FONT><BR></P></DIV>

<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#009900>//: C10:Arithmetic.cpp</font>
#include <font color=#004488>"NamespaceInt.h"</font>
<font color=#0000ff>void</font> arithmetic() {
  <font color=#0000ff>using</font> <font color=#0000ff>namespace</font> Int;
  Integer x;
  x.setSign(positive);
}
<font color=#0000ff>int</font> main(){} <font color=#009900>///:~</font></PRE></FONT></BLOCKQUOTE>

<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Without the <B>using</B> directive, all
the names in the namespace would need to be fully qualified.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">One aspect of the <B>using</B> directive
may seem slightly counterintuitive at first. The visibility of the names
introduced with a <B>using</B> directive is the scope in which the directive is
made. But you can override the names from the <B>using</B> directive as if
they&#8217;ve been declared globally to that scope! </FONT><BR></P></DIV>

<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#009900>//: C10:NamespaceOverriding1.cpp</font>
#include <font color=#004488>"NamespaceMath.h"</font>
<font color=#0000ff>int</font> main() {
  <font color=#0000ff>using</font> <font color=#0000ff>namespace</font> Math;
  Integer a; <font color=#009900>// Hides Math::a;</font>
  a.setSign(negative);
  <font color=#009900>// Now scope resolution is necessary</font>

⌨️ 快捷键说明

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