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

📄 ec7.htm

📁 一个非常适合初学者入门的有关c++的文档
💻 HTM
📖 第 1 页 / 共 5 页
字号:
<P><A NAME="dingp73"></A>
Practically speaking, then, this is the C++ header <NOBR>situation:<SCRIPT>create_link(73);</SCRIPT>

</NOBR></P>
<UL><A NAME="26890"></A>
<A NAME="dingp74"></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(74);</SCRIPT>

<A NAME="28058"></A>
<A NAME="dingp75"></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(75);</SCRIPT>

<A NAME="28059"></A>
<A NAME="dingp76"></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(76);</SCRIPT>

<A NAME="26892"></A>
<A NAME="dingp77"></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(77);</SCRIPT>

</UL></P>
<A NAME="26830"></A>
<P><A NAME="dingp78"></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(78);</SCRIPT>

</NOBR></P>
<A NAME="27012"></A>
<P><A NAME="dingp79"></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="./EC1_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(79);</SCRIPT>

</P>
<A NAME="195340"></A>
<P><A NAME="dingp80"></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(80);</SCRIPT>

</NOBR></P>
<A NAME="27044"></A>
<P><A NAME="dingp81"></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(81);</SCRIPT>

</P>
<A NAME="27047"></A>
<P><A NAME="dingp82"></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="./EC2_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(82);</SCRIPT>

</NOBR></P>
<A NAME="223087"></A>
<P><A NAME="dingp83"></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(83);</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="dingp84"></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(84);</SCRIPT>

</P>
<A NAME="27132"></A>
<P><A NAME="dingp85"></A>
Well, usually you can. Sometimes you have to peek under the hood a bit. For example, <A HREF="./EC5_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(85);</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="223637"></A>
<A NAME="p228"></A>
<P><A NAME="dingp86"></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(86);</SCRIPT>
</P>
<UL><PRE>typedef basic_string&lt;char&gt; string;
</PRE>
</UL><A NAME="223638"></A>

<P><A NAME="dingp87"></A>
but that won't compile. "What is this <CODE>basic_string</CODE> of which you speak?," your compilers will wonder, though they'll probably phrase the question rather differently. No, to declare <CODE>string</CODE>, you would first have to declare all the templates on which it depends. If you could do it, it would look something like <NOBR>this:<SCRIPT>create_link(87);</SCRIPT>

</NOBR></P>
<A NAME="223639"></A>
<UL><PRE>template&lt;class charT&gt; struct char_traits;
</PRE>
</UL><A NAME="223640"></A>
<UL><PRE>template&lt;class T&gt; class allocator;
</PRE>
</UL><A NAME="223641"></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="223642"></A>
<UL><PRE>typedef basic_string&lt;char&gt; string;
</PRE>
</UL><A NAME="223643"></A>
<A NAME="dingp88"></A>However, you can't declare <CODE>string</CODE>. At least you shouldn't. That's because library implementers are allowed to declare <CODE>string</CODE> (or anything else in the <CODE>std</CODE> namespace) differently from what's specified in <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">the</NOBR> standard</A> as long as the result offers standard-conforming behavior. For example, a <CODE>basic_string</CODE> implementation could add a fourth template parameter, but that parameter's default value would have to yield code that acts as the standard says an unadorned <CODE>basic_string</CODE> <NOBR>must.<SCRIPT>create_link(88);</SCRIPT>

</NOBR></P>
<A NAME="223644"></A>
<P><A NAME="dingp89"></A>
End result? Don't try to manually declare <CODE>string</CODE> (or any other part of the standard library). Instead, just include the appropriate header, e.g. <CODE>&lt;string&gt;</CODE>.<SCRIPT>create_link(89);</SCRIPT>

</P>
<A NAME="223646"></A>
<P><A NAME="dingp90"></A>
With this background on headers and templates under our belts, we're in a position to survey the primary components of the standard C++ <NOBR>library:<SCRIPT>create_link(90);</SCRIPT>

</NOBR></P><UL><A NAME="223648"></A>
<A NAME="dingp91"></A><LI><B>The standard C library.</B> It's still there, and you can still use it. A few minor things have been tweaked here and there, but for all intents and purposes, it's the same C library that's been around for years.<SCRIPT>create_link(91);</SCRIPT>

<A NAME="223651"></A>
<P><A NAME="dingp92"></A><LI><B>Iostreams.</B> Compared to "traditional" iostream implementations, it's been templatized, its inheritance hierarchy has been modified, it's been augmented with the ability to throw exceptions, and it's been updated to support strings (via the <CODE>stringstream</CODE> classes) and internationalization (via locales &#151; see below). Still, most everything you've come to expect from the iostream library continues to exist. In particular, it still supports stream buffers, formatters, manipulators, and files, plus the objects <CODE>cin</CODE>, <CODE>cout</CODE>, <CODE>cerr</CODE>, and <CODE><A NAME="p229"></A>clog</CODE>. That means you can treat <CODE>string</CODE>s and files as streams, and you have extensive control over stream behavior, including buffering and formatting.<SCRIPT>create_link(92);</SCRIPT>

</P>
<A NAME="223665"></A>
<P>
<A NAME="28081"></A>

<A NAME="dingp93"></A><LI><B>Strings.</B> <CODE>string</CODE> objects were designed to eliminate the need to use <CODE>char*</CODE> pointers in most applications. They support the operations you'd expect (e.g., concatenation, constant-time access to individual characters via <CODE>operator[]</CODE>, etc.), they're convertible to <CODE>char*</CODE>s for compatibility with legacy code, and they handle memory management automatically. Some <CODE>string</CODE> implementations employ reference counting (see <A HREF="../MEC/MC5_FR.HTM#6073" TARGET="_top">Item M29</A>), which can lead to <I>better</I> performance (in both time and space) than <CODE>char*</CODE>-based strings.<SCRIPT>create_link(93);</SCRIPT>

<A NAME="183443"></A>
<P>
<A NAME="dingp94"></A><LI><B>Containers.</B> Stop writing your own basic container classes! The library offers efficient implementations of vectors (they act like dynamically extensible arrays), lists (doubly-linked), queues, stacks, deques, maps, sets, and bitsets. Alas, there are no hash tables in the library (though many vendors offer them as extensions), but compensating somewhat is the fact that <CODE>string</CODE>s are containers. That's important, because it means anything you can do to a container (see below), you can also do to a <CODE>string</CODE>.<SCRIPT>create_link(94);</SCRIPT>

<A NAME="195382"></A>
<P>
What's that? You want to know how I <I>know</I> the library implementations are efficient? Easy: the library specifies each class's interface, and part of each interface specification is a set of performance guarantees. So, for example, no matter how <CODE>vector</CODE> is implemented, it's not enough to offer just <I>access</I> to its elements, it must offer <I>constant-time</I> access. If it doesn't, it's not a valid <CODE>vector</CODE> <NOBR>implementation.<SCRIPT>create_link(95);</SCRIPT>

</NOBR></P>
<A NAME="195384"></A>
<P><A NAME="dingp96"></A>
In many C++ programs, dynamically allocated strings and arrays account for most uses of <CODE>new</CODE> and <CODE>delete</CODE>, and <CODE>new</CODE>/<CODE>delete</CODE> errors &#151; especially leaks caused by failure to delete <CODE>new</CODE>ed memory &#151; are distressingly common. If you use <CODE>string</CODE> and <CODE>vector</CODE> objects (both of which perform their own memory management) instead of <CODE>char*</CODE>s and pointers to dynamically allocated arrays, many of your <CODE>new</CODE>s and <CODE>delete</CODE>s will vanish, and so will the difficulties that frequently accompany their use (e.g., Items <A HREF="./EC2_FR.HTM#1885" TARGET="_top">6</A> and <A HREF="./EC3_FR.HTM#2042" TARGET="_top">11</A>).<SCRIPT>create_link(96);</SCRIPT>

</P>
<A NAME="27223"></A>
<A NAME="dingp97"></A><LI><B>Algorithms.</B> Having standard containers is nice, but it's even nicer when there's an easy way to do things with them. The standard library offers over two dozen easy ways (i.e., predefined functions, officially known as <I>algorithms</I> &#151; they're really function templates), most of which work with <I>all</I> the containers in the library &#151; as well as with built-in arrays!<SCRIPT>create_link(97);</SCRIPT>

<A NAME="27863"></A>
<P><A NAME="dingp98"></A>
<A NAME="p230"></A>Algorithms treat the contents of a container as a sequence, and each algorithm may be applied to either the sequence corresponding to all the values in a container or to a subsequence. Among the standard algorithms are <CODE>for_each</CODE> (apply a function to each element of a sequence), <CODE>find</CODE> (find the first location in a sequence holding a given value &#151; <A HREF="../MEC/MC6_FR.HTM#5473" TARGET="_top">Item M35</A> shows its implementation), <CODE>count_if</CODE> (count the number of elements in a sequence for which a given predicate is true), <CODE>equal</CODE> (determine whether two sequences hold equal-valued elements), <CODE>search</CODE> (find the first position in one sequence where a second sequence occurs as a subsequence), <CODE>copy</CODE> (copy one sequence into another), <CODE>unique</CODE> (remove duplicate values from a sequence), <CODE>rotate</CODE> (rotate the values in a sequence) and <CODE>sort</CODE> (sort the values in a sequence). Note that this is just a <I>sampling</I> of the algorithms available; the library contains many <NOBR>others.<SCRIPT>create_link(98);</SCRIPT>

</NOBR></P>
<A NAME="27824"></A>
<P><A NAME="dingp99"></A>
Just as container operations come with performance guarantees, so do algorithms. For example, the <CODE>stable_sort</CODE> algorithm is required to perform no more than O(N log N) comparisons. (If the "Big O" notation in the previous sentence is foreign to you, don't sweat it. What it really means is that, broadly speaking, <CODE>stable_sort</CODE> must offer performance at the same level as the most efficient general-purpose serial sorting <NOBR>algorithms.)<SCRIPT>create_link(99);</SCRIPT>

</NOBR></P>
<A NAME="27840"></A>
<A NAME="dingp100"></A><LI><B>Support for internationalization.</B> Different cultures do things in different ways. Like the C library, the C++ library offers features to facilitate the production of internationalized software, but the C++ approach, though conceptually akin to that of C, is different. It should not surprise you, for example, to learn that C++'s support for internationalization makes extensive use of templates, and it takes advantage of inheritance and virtual functions, too.<SCRIPT>create_link(100);</SCRIPT>

<A NAME="27747"></A>
<P><A NAME="dingp101"></A>
The primary library components supporting internationalization are <I>facets</I> and <I>locales</I>. Facets describe how particular characteristics of a culture should be handled, including collation rules (i.e., how strings in the local character set should be sorted), how dates and times should be expressed, how numeric and monetary values should be presented, how 

⌨️ 快捷键说明

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