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

📄 ei28.htm

📁 一个非常适合初学者入门的有关c++的文档
💻 HTM
📖 第 1 页 / 共 2 页
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN" "http://www.w3.org/TR/REC-html40/frameset.dtd">
<HTML LANG="EN">
<HEAD>
<title>Effective C++, 2E | Item 28: Partition the global namespace</TITLE>
<LINK REL=STYLESHEET HREF=../INTRO/ECMEC.CSS>

<SCRIPT LANGUAGE="Javascript" SRC="../JAVA/COOKIE.JS"></SCRIPT>
<SCRIPT LANGUAGE="Javascript">var imagemax = 0; setCurrentMax(0);</SCRIPT>
<SCRIPT LANGUAGE="Javascript" SRC="../JAVA/DINGBATS.JS"></SCRIPT>
<SCRIPT LANGUAGE="Javascript">
var dingbase = "EI28_DIR.HTM";
var dingtext = "Item E28, P";
if (self == top) {
 top.location.replace(dingbase + this.location.hash);
}
</SCRIPT>

</HEAD>
<BODY BGCOLOR="#FFFFFF" TEXT="#000000" ONLOAD="setResize()">
<!-- SectionName="E28: Partition the global namespace" -->
<A NAME="6429"></A>
<DIV ALIGN="CENTER"><FONT SIZE="-1">Back to <A HREF="./EI27_FR.HTM" TARGET="_top">Item 27: Explicitly disallow use of implicitly generated member functions you don't want.</A> &nbsp;&nbsp;<BR>&nbsp;&nbsp;Continue to <A HREF="./EIMPL_FR.HTM" TARGET="_top">Classes and Functions: Implementation </A></FONT></DIV>

<P><A NAME="dingp1"></A><FONT ID="eititle">Item 28: &nbsp;Partition the global namespace.</FONT><SCRIPT>create_link(1);</SCRIPT>
</P>

<A NAME="6434"></A>
<P><A NAME="dingp2"></A>
The biggest problem with the global scope is that there's only one of them. In a large software project, there is usually a bevy of people putting names in this singular scope, and invariably this leads to name conflicts. For example, <CODE>library1.h</CODE> might define a number of constants, including the <NOBR>following:<SCRIPT>create_link(2);</SCRIPT>
</NOBR></P>
<A NAME="6437"></A>
<UL><PRE>const double LIB_VERSION = 1.204;
</PRE>
</UL><A NAME="6438"></A>
<P><A NAME="dingp3"></A>
Ditto for <CODE>library2.h</CODE>:<SCRIPT>create_link(3);</SCRIPT>

<A NAME="6439"></A>
<UL><PRE>const int LIB_VERSION = 3;
</PRE>
</UL></P><A NAME="6440"></A>
<P><A NAME="dingp4"></A>
It doesn't take great insight to see that there is going to be a problem if a program tries to include both <CODE>library1.h</CODE> and <CODE>library2.h</CODE>. Unfortunately, outside of cursing under your breath, sending hate mail to the library authors, and editing the header files until the name conflicts are eliminated, there is little you can do about this kind of <NOBR>problem.<SCRIPT>create_link(4);</SCRIPT>
</NOBR></P>
<A NAME="6441"></A>
<P><A NAME="dingp5"></A>
You can, however, take pity on the poor souls who'll have <EM>your</EM> libraries foisted on them. You probably already prepend some hopefully-unique prefix to each of your global symbols, but surely you must admit that the resulting identifiers are less than pleasing to gaze <NOBR>upon.<SCRIPT>create_link(5);</SCRIPT>
</NOBR></P>
<A NAME="25982"></A>
<P><A NAME="dingp6"></A>
A better solution is to use a C++ <CODE>namespace</CODE>. Boiled down to its essence, a <CODE>namespace</CODE> is just a fancy way of letting you use the prefixes you know and love without making people look at them all the time. So instead of <NOBR>this,<SCRIPT>create_link(6);</SCRIPT>
</NOBR></P>
<A NAME="223195"></A>
<UL><PRE>
const double sdmBOOK_VERSION = 2.0;      // in this library,
                                         // each symbol begins
class sdmHandle { ... };                 // with "sdm"

sdmHandle&amp; sdmGetHandle();             // see <A HREF="./EI47_FR.HTM#8299" TARGET="_top">Item 47</A> for why you
                                       // might want to declare
                                       // a function like this
</PRE>
</UL><A NAME="26023"></A>
<A NAME="dingp7"></A>you write <NOBR>this:<SCRIPT>create_link(7);</SCRIPT>
</NOBR></P>
<A NAME="26024"></A>
<UL><PRE><A NAME="p118"></A>namespace sdm {
  const double BOOK_VERSION = 2.0;
  class Handle { ... };
  Handle&amp; getHandle();
}
</PRE>
</UL><A NAME="25980"></A>
<P><A NAME="dingp8"></A>
Clients then access symbols in your namespace in any of the usual three ways: by importing all the symbols in a namespace into a scope, by importing individual symbols into a scope, or by explicitly qualifying a symbol for one-time use. Here are some <NOBR>examples:<SCRIPT>create_link(8);</SCRIPT>
</NOBR></P>
<A NAME="26054"></A>
<UL><PRE>void f1()
{
  using namespace sdm;           // make all symbols in sdm
                                 // available w/o qualification
                                 // in this scope
</PRE>
</UL><A NAME="26051"></A>
<UL><PRE>
  cout &lt;&lt; BOOK_VERSION;          // okay, resolves to
                                 // sdm::BOOK_VERSION
  ...
</PRE>
</UL><A NAME="26031"></A>
<UL><PRE>
  Handle h = getHandle();        // okay, Handle resolves to
                                 // sdm::Handle, getHandle
  ...                            // resolves to sdm::getHandle
</PRE>
</UL><A NAME="26039"></A>
<UL><PRE>}
</PRE>
</UL><A NAME="26030"></A>
<UL><PRE>void f2()
{
  using sdm::BOOK_VERSION;        // make only BOOK_VERSION
                                  // available w/o qualification
                                  // in this scope
</PRE>
</UL><A NAME="26035"></A>
<UL><PRE>
  cout &lt;&lt; BOOK_VERSION;           // okay, resolves to
                                  // sdm::BOOK_VERSION
  ...
</PRE>
</UL><A NAME="26037"></A>
<UL><PRE>
  Handle h = getHandle();         // error! neither Handle
                                  // nor getHandle were
  ...                             // imported into this scope
</PRE>
</UL><A NAME="26041"></A>
<UL><PRE>}
</PRE>
</UL><A NAME="26028"></A>
<UL><PRE>void f3()
{
  cout &lt;&lt; sdm::BOOK_VERSION;      // okay, makes BOOK_VERSION
                                  // available for this one use
  ...                             // only
</PRE>
</UL><A NAME="26055"></A>
<UL><PRE>
  double d = BOOK_VERSION;        // error! BOOK_VERSION is
                                  // not in scope
</PRE>
</UL><A NAME="26459"></A>
<UL><PRE>
  Handle h = getHandle();         // error! neither Handle
                                  // nor getHandle were
  ...                             // imported into this scope
</PRE>
</UL><A NAME="26063"></A>
<UL><PRE>}
</PRE>
</UL><A NAME="223371"></A>
<P><A NAME="dingp9"></A>
<A NAME="p119"></A>(Some namespaces have no names. Such <I>unnamed namespaces</I> are used to limit the visibility of the elements inside the namespace. For details, see <A HREF="../MEC/MI31_FR.HTM#34883" TARGET="_top">Item M31</A>.)<SCRIPT>create_link(9);</SCRIPT>
</P>
<A NAME="26060"></A>
<P><A NAME="dingp10"></A>
One of the nicest things about namespaces is that potential ambiguity is not an error (see <A HREF="./EI26_FR.HTM#6337" TARGET="_top">Item 26</A>). As a result, you can import the same symbol from more than one namespace, yet still live a carefree life (provided you never actually use the symbol). For instance, if, in addition to namespace <CODE>sdm</CODE>, you had need to make use of this <NOBR>namespace,<SCRIPT>create_link(10);</SCRIPT>
</NOBR></P>
<A NAME="26070"></A>
<UL><PRE>namespace AcmeWindowSystem {
</PRE>
</UL><A NAME="26071"></A>
<UL><PRE>  ...
</PRE>
</UL><A NAME="26072"></A>
<UL><PRE>  typedef int Handle;
</PRE>
</UL><A NAME="26073"></A>
<UL><PRE>  ...
</PRE>
</UL><A NAME="26074"></A>
<UL><PRE>}
</PRE>
</UL><A NAME="26075"></A>
<P><A NAME="dingp11"></A>
you could use both <CODE>sdm</CODE> and <CODE>AcmeWindowSystem</CODE> without conflict, provided you never referenced the symbol <CODE>Handle</CODE>. If you did refer to it, you'd have to explicitly say which namespace's <CODE>Handle</CODE> you <NOBR>wanted:<SCRIPT>create_link(11);</SCRIPT>
</NOBR></P>
<A NAME="26080"></A>
<UL><PRE>void f()
{
  using namespace sdm;                 // import sdm symbols
  using namespace AcmeWindowSystem;    // import Acme symbols
</PRE>
</UL><A NAME="26089"></A>
<UL><PRE>
  ...                                  // freely refer to sdm
                                       // and Acme symbols
                                       // other than Handle

⌨️ 快捷键说明

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