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

📄 ei49.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 49: Familiarize yourself with the standard library</TITLE>
<LINK REL=STYLESHEET HREF=../INTRO/ECMEC.CSS>

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

</HEAD>
<BODY BGCOLOR="#FFFFFF" TEXT="#000000" ONLOAD="setResize()">
<!-- SectionName="E49: Be familiar with the standard library" -->
<A NAME="8392"></A>
<DIV ALIGN="CENTER"><FONT SIZE="-1">Back to <A HREF="EI48_FR.HTM" TARGET="_top">Item 48: Pay attention to compiler warnings.</A> &nbsp;&nbsp;<BR>&nbsp;&nbsp;Continue to <A HREF="EI50_FR.HTM" TARGET="_top">Item 50: Improve your understanding of C++.</A></DIV></FONT>

<P><A NAME="dingp1"></A><FONT ID="eititle">Item 49: &nbsp;Familiarize yourself with the standard library.</FONT><SCRIPT>create_link(1);</SCRIPT>

</P>

<A NAME="26771"></A>
<P><A NAME="dingp2"></A>
C++'s standard library is big. Very big. Incredibly big. How big? Let me put it this way: the specification takes over 300 closely-packed pages in the <NOBR><FONT COLOR="#FF0000" SIZE="-2"><B>&deg;</B></FONT><A HREF="http://www.awl.com/cseng/cgi-bin/cdquery.pl?name=cstandard" onMouseOver = "self.status = 'The latest publicly-available version of the C++ standard'; return true" onMouseOut = "self.status = self.defaultStatus" TARGET="_top">C++</NOBR> standard</A>, and that all but excludes the standard C library, <A NAME="p225"></A>which is included in the C++ library "by reference." (That's the term they use, <NOBR>honest.)<SCRIPT>create_link(2);</SCRIPT>

</NOBR></P>
<A NAME="26772"></A>
<P><A NAME="dingp3"></A>
Bigger isn't always better, of course, but in this case, bigger <I>is</I> better, because a big library contains lots of functionality. The more functionality in the standard library, the more functionality you can lean on as you develop your applications. The C++ library doesn't offer <I>everything</I> (support for concurrency and for graphical user interfaces is notably absent), but it does offer a lot. You can lean almost anything against <NOBR>it.<SCRIPT>create_link(3);</SCRIPT>

</NOBR></P>
<A NAME="26831"></A>
<P><A NAME="dingp4"></A>
Before summarizing what's in the library, I need to tell you a bit about how it's organized. Because the library has so much in it, there's a reasonable chance you (or someone like you) may choose a class or function name that's the same as a name in the standard library. To shield you from the name conflicts that would result, virtually everything in the standard library is nestled in the namespace <CODE>std</CODE> (see <A HREF="./EI28_FR.HTM#6429" TARGET="_top">Item 28</A>). But that leads to a new problem. Gazillions of lines of existing C++ rely on functionality in the pseudo-standard library that's been in use for years, e.g., functionality declared in the headers <CODE>&lt;iostream.h&gt;</CODE>, <CODE>&lt;complex.h&gt;</CODE>, <CODE>&lt;limits.h&gt;</CODE>, etc. That existing software isn't designed to use namespaces, and it would be a shame if wrapping the standard library by <CODE>std</CODE> caused the existing code to break. (Authors of the broken code would likely use somewhat harsher language than "shame" to describe their feelings about having the library rug pulled out from underneath <NOBR>them.)<SCRIPT>create_link(4);</SCRIPT>

</NOBR></P>
<A NAME="26873"></A>
<P><A NAME="dingp5"></A>
Mindful of the destructive power of rioting bands of incensed programmers, the <NOBR><FONT COLOR="#FF0000" SIZE="-2"><B>&deg;</B></FONT><A HREF="http://www.awl.com/cseng/cgi-bin/cdquery.pl?name=committee" onMouseOver = "self.status = 'Link to the C++ Standardization Committee'; return true" onMouseOut = "self.status = self.defaultStatus" TARGET="_top">standardization</NOBR> committee</A> decided to create new header names for the <CODE>std</CODE>-wrapped components. The algorithm they chose for generating the new header names is as trivial as the results it produces are jarring: the <CODE>.h</CODE> on the existing C++ headers was simply dropped. So <CODE>&lt;iostream.h&gt;</CODE> became <CODE>&lt;iostream&gt;</CODE>, <CODE>&lt;complex.h&gt;</CODE> became <CODE>&lt;complex&gt;</CODE>, etc. For C headers, the same algorithm was applied, but a <CODE>c</CODE> was prepended to each result. Hence C's <CODE>&lt;string.h&gt;</CODE> became <CODE>&lt;cstring&gt;</CODE>, <CODE>&lt;stdio.h&gt;</CODE> became <CODE>&lt;cstdio&gt;</CODE>, etc. For a final twist, the old C++ headers were officially <I>deprecated</I> (i.e., listed as no longer supported), but the old C headers were not (to maintain C compatibility). In practice, compiler vendors have no incentive to disavow their customers' legacy software, so you can expect the old C++ headers to be supported for many <NOBR>years.<SCRIPT>create_link(5);</SCRIPT>

</NOBR></P>
<A NAME="28169"></A>
<P><A NAME="dingp6"></A>
Practically speaking, then, this is the C++ header <NOBR>situation:<SCRIPT>create_link(6);</SCRIPT>

</NOBR></P>
<UL><A NAME="26890"></A>
<A NAME="dingp7"></A><LI>Old C++ header names like <CODE>&lt;iostream.h&gt;</CODE> are likely to continue to be supported, even though they aren't in the <NOBR><FONT COLOR="#FF0000" SIZE="-2"><B>&deg;</B></FONT><A HREF="http://www.awl.com/cseng/cgi-bin/cdquery.pl?name=cstandard" onMouseOver = "self.status = 'The latest publicly-available version of the C++ standard'; return true" onMouseOut = "self.status = self.defaultStatus" TARGET="_top">official</NOBR> standard</A>. The contents of such headers are <I>not</I> in namespace <CODE>std</CODE>.<SCRIPT>create_link(7);</SCRIPT>

<A NAME="28058"></A>
<A NAME="dingp8"></A><LI><A NAME="p226"></A>New C++ header names like <CODE>&lt;iostream&gt;</CODE> contain the same basic functionality as the corresponding old headers, but the contents of the headers <I>are</I> in namespace <CODE>std</CODE>. (During standardization, the details of some of the library components were modified, so there isn't necessarily an exact match between the entities in an old C++ header and those in a new one.)<SCRIPT>create_link(8);</SCRIPT>

<A NAME="28059"></A>
<A NAME="dingp9"></A><LI>Standard C headers like <CODE>&lt;stdio.h&gt;</CODE> continue to be supported. The contents of such headers are <I>not</I> in <CODE>std</CODE>.<SCRIPT>create_link(9);</SCRIPT>

<A NAME="26892"></A>
<A NAME="dingp10"></A><LI>New C++ headers for the functionality in the C library have names like <CODE>&lt;cstdio&gt;</CODE>. They offer the same contents as the corresponding old C headers, but the contents <I>are</I> in <CODE>std</CODE>.<SCRIPT>create_link(10);</SCRIPT>

</UL></P>
<A NAME="26830"></A>
<P><A NAME="dingp11"></A>
All this seems a little weird at first, but it's really not that hard to get used to. The biggest challenge is keeping all the string headers straight: <CODE>&lt;string.h&gt;</CODE> is the old C header for <CODE>char*</CODE>-based string manipulation functions, <CODE>&lt;string&gt;</CODE> is the <CODE>std</CODE>-wrapped C++ header for the new string classes (see below), and <CODE>&lt;cstring&gt;</CODE> is the <CODE>std</CODE>-wrapped version of the old C header. If you can master that (and I know you can), the rest of the library is <NOBR>easy.<SCRIPT>create_link(11);</SCRIPT>

</NOBR></P>
<A NAME="27012"></A>
<P><A NAME="dingp12"></A>
The next thing you need to know about the standard library is that almost everything in it is a template. Consider your old friend iostreams. (If you and iostreams aren't friends, turn to <A HREF="./EI2_FR.HTM#95970" TARGET="_top">Item 2</A> to find out why you should cultivate a relationship.) Iostreams help you manipulate streams of characters, but what's a character? Is it a <CODE>char</CODE>? A <CODE>wchar_t</CODE>? A Unicode character? Some other multi-byte character? There's no obviously right answer, so the library lets you choose. All the stream classes are really class templates, and you specify the character type when you instantiate a stream class. For example, the standard library defines the type of <CODE>cout</CODE> to be <CODE>ostream</CODE>, but <CODE>ostream</CODE> is really a typedef for <CODE>basic_ostream&lt;char&gt;</CODE>.<SCRIPT>create_link(12);</SCRIPT>

</P>
<A NAME="195340"></A>
<P><A NAME="dingp13"></A>
Similar considerations apply to most of the other classes in the standard library. <CODE>string</CODE> isn't a class, it's a class template: a type parameter defines the type of characters in each <CODE>string</CODE> class. <CODE>complex</CODE> isn't a class, it's a class template: a type parameter defines the type of the real and imaginary components in each <CODE>complex</CODE> class. <CODE>vector</CODE> isn't a class, it's a class template. On and on it <NOBR>goes.<SCRIPT>create_link(13);</SCRIPT>

</NOBR></P>
<A NAME="27044"></A>
<P><A NAME="dingp14"></A>
You can't escape the templates in the standard library, but if you're used to working with only streams and strings of <CODE>char</CODE>s, you can mostly ignore them. That's because the library defines typedefs for <CODE>char</CODE> instantiations for these components of the library, thus letting you continue to program in terms of the objects <CODE>cin</CODE>, <CODE>cout</CODE>, <CODE>cerr</CODE>, etc., and the types <CODE>istream</CODE>, <CODE>ostream</CODE>, <CODE>string</CODE>, etc., without having to <A NAME="p227"></A>worry about the fact that <CODE>cin</CODE>'s real type is <CODE>basic_istream&lt;char&gt;</CODE> and <CODE>string</CODE>'s is <CODE>basic_string&lt;char&gt;</CODE>.<SCRIPT>create_link(14);</SCRIPT>

</P>
<A NAME="27047"></A>
<P><A NAME="dingp15"></A>
Many components in the standard library are templatized much more than this suggests. Consider again the seemingly straightforward notion of a string. Sure, it can be parameterized based on the type of characters it holds, but different character sets differ in details, e.g., special end-of-file characters, most efficient way of copying arrays of them, etc. Such characteristics are known in the standard as <I>traits</I>, and they are specified for <CODE>string</CODE> instantiations by an additional template parameter. In addition, <CODE>string</CODE> objects are likely to perform dynamic memory allocation and deallocation, but there are lots of different ways to approach that task (see <A HREF="./EI10_FR.HTM#1986" TARGET="_top">Item 10</A>). Which is best? You get to choose: the <CODE>string</CODE> template takes an <CODE>Allocator</CODE> parameter, and objects of type <CODE>Allocator</CODE> are used to allocate and deallocate the memory used by <CODE>string</CODE> <NOBR>objects.<SCRIPT>create_link(15);</SCRIPT>

</NOBR></P>
<A NAME="223087"></A>
<P><A NAME="dingp16"></A>
Here's a full-blown declaration for the <CODE>basic_string</CODE> template and the <CODE>string</CODE> typedef that builds on it; you can find this (or something equivalent to it) in the header <CODE>&lt;string&gt;</CODE>:<SCRIPT>create_link(16);</SCRIPT>

</P>
<A NAME="27479"></A>
<UL><PRE>namespace std {
</PRE>
</UL><A NAME="27483"></A>
<UL><PRE>  template&lt;class charT,
           class traits = char_traits&lt;charT&gt;,
           class Allocator = allocator&lt;charT&gt; &gt;
     class basic_string;
</PRE>
</UL><A NAME="27467"></A>
<UL><PRE>  typedef basic_string&lt;char&gt; string;
</PRE>
</UL><A NAME="27134"></A>
<UL><PRE>}
</PRE>
</UL></P><A NAME="28200"></A>
<P><A NAME="dingp17"></A>
Notice how <CODE>basic_string</CODE> has default values for its <CODE>traits</CODE> and <CODE>Allocator</CODE> parameters. This is typical of the standard library. It offers flexibility to those who need it, but "typical" clients who just want to do the "normal" thing can ignore the complexity that makes possible the flexibility. In other words, if you just want string objects that act more or less like C strings, you can use <CODE>string</CODE> objects and remain merrily ignorant of the fact that you're really using objects of type <CODE>basic_string&lt;char,</CODE> <CODE>char_traits&lt;char&gt;,</CODE> <CODE>allocator&lt;char&gt;</CODE> <CODE>&gt;</CODE>.<SCRIPT>create_link(17);</SCRIPT>

</P>
<A NAME="27132"></A>
<P><A NAME="dingp18"></A>
Well, usually you can. Sometimes you have to peek under the hood a bit. For example, <A HREF="./EI34_FR.HTM#6793" TARGET="_top">Item 34</A> discusses the advantages of declaring a class without providing its definition, and it remarks that the following is the wrong way to declare the <CODE>string</CODE> <NOBR>type:<SCRIPT>create_link(18);</SCRIPT>

</NOBR></P>
<A NAME="27376"></A>
<UL><PRE>
class string;                   // this will compile, but
                                // you don't want to do it
</PRE>
</UL></NOBR></P>
<A NAME="p228"></A>
<P><A NAME="dingp19"></A>Setting aside namespace considerations for a moment, the real problem here is that <code>string</code> isn't a class, it's a typedef. It would be nice if you could solve the problem this way:<SCRIPT>create_link(19);</SCRIPT>
</P>
<A NAME="223637"></A>
<UL><PRE>typedef basic_string&lt;char&gt; string;
</PRE>
</UL><A NAME="223638"></A>

⌨️ 快捷键说明

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