📄 mi35.htm
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN" "http://www.w3.org/TR/REC-html40/frameset.dtd">
<HTML LANG="EN">
<HEAD>
<TITLE>More Effective C++ | Item 35: Familiarize yourself with the language standard</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 = "MI35_DIR.HTM";
var dingtext = "Item M35, P";
if (self == top) {
top.location.replace(dingbase + this.location.hash);
}
</SCRIPT>
</HEAD>
<BODY BGCOLOR="#FFFFFF" TEXT="#000000" ONLOAD="setResize()">
<!-- SectionName="M35: Be familiar with the language standard" -->
<A NAME="5473"></A>
<DIV ALIGN="CENTER"><FONT SIZE="-1">Back to <A HREF="./MI34_FR.HTM" TARGET="_top">Item 34: Understand how to combine C++ and C in the same program</A> <BR> Continue to <A HREF="./MIREADFR.HTM" TARGET="_top">Recommended Reading</A></FONT></DIV>
<A NAME="p277"></A>
<P><A NAME="dingp1"></A><font ID="mititle">Item 35: Familiarize yourself with <NOBR><FONT COLOR="#FF0000" SIZE="-2"><B>°</B></FONT><A HREF="http://www.awl.com/cseng/cgi-bin/cdquery.pl?name=cstandard" onMouseOver="self.status='C++ Language Standard Home Page'; return true" onMouseOut="self.status = self.defaultStatus" target="_top">the</NOBR> language
standard</A>.</font><SCRIPT>create_link(1);</SCRIPT>
</P>
<A NAME="72198"></A>
<A NAME="46843"></A>
<P><A NAME="dingp2"></A>
Since its publication in 1990, <NOBR><FONT COLOR="#FF0000" SIZE="-2"><B>°</B></FONT><A HREF="http://www.awl.com/cseng/cgi-bin/cdquery.pl?name=anncrm" onMouseOver="self.status='The Annotated C++ Reference Manual Home Page'; return true" onMouseOut="self.status = self.defaultStatus" target="_top"><I>The</NOBR> Annotated C++ Reference Manual</I></A> (see <a href="./MIREADFR.HTM#p285" TARGET="_top">page 285</A>) has been the definitive reference for working programmers needing to know what is in C++ and what is not. In the years since the ARM (as it's fondly known) came out, the <NOBR><FONT COLOR="#FF0000" SIZE="-2"><B>°</B></FONT><A HREF="http://www.awl.com/cseng/cgi-bin/cdquery.pl?name=committee" onMouseOver="self.status='ISO/ANSI Language Standardization Committee Home Page'; return true" onMouseOut="self.status = self.defaultStatus" target="_top">ISO/ANSI</NOBR> committee standardizing the language</A> has changed (primarily extended) the language in ways both big and small. As a definitive reference, the ARM no longer <NOBR>suffices.<SCRIPT>create_link(2);</SCRIPT>
</NOBR></P>
<A NAME="46858"></A>
<P><A NAME="dingp3"></A>
The post-ARM changes to C++ significantly affect how good programs are written. As a result, it is important for C++ programmers to be familiar with the primary ways in which the C++ specified by the standard differs from that described by the <NOBR>ARM.<SCRIPT>create_link(3);</SCRIPT>
</NOBR></P>
<A NAME="47097"></A>
<P><A NAME="dingp4"></A>
The <NOBR><FONT COLOR="#FF0000" SIZE="-2"><B>°</B></FONT><A HREF="http://www.awl.com/cseng/cgi-bin/cdquery.pl?name=cstandard" onMouseOver="self.status='ISO/ANSI Standard for C++ Home Page'; return true" onMouseOut="self.status = self.defaultStatus" target="_top">ISO/ANSI</NOBR> standard for C++</A> is what vendors will consult when implementing compilers, what authors will examine when preparing books, and what programmers will look to for definitive answers to questions about C++. Among the most important changes to C++ since the ARM are the <NOBR>following:<SCRIPT>create_link(4);</SCRIPT>
</NOBR></P>
<UL><A NAME="46975"></A>
<A NAME="dingp5"></A><LI><B>New features have been added</B>: RTTI, namespaces, <CODE>bool</CODE>, the <CODE>mutable</CODE> and <CODE>explicit</CODE> keywords, the ability to overload operators for enums, and the ability to initialize constant integral static class members within a class definition.<SCRIPT>create_link(5);</SCRIPT>
<A NAME="46983"></A>
<A NAME="dingp6"></A><LI><B>Templates have been extended</B>: member templates are now allowed, there is a standard syntax for forcing template instantiations, non-type arguments are now allowed in function templates, and class templates may themselves be used as template arguments.<SCRIPT>create_link(6);</SCRIPT>
<A NAME="46996"></A>
<A NAME="dingp7"></A><LI><B>Exception handling has been refined</B>: exception specifications are now more rigorously checked during compilation, and the <CODE>unexpected</CODE> function may now throw a <CODE>bad_exception</CODE> object.<SCRIPT>create_link(7);</SCRIPT>
<A NAME="46999"></A>
<A NAME="dingp8"></A><LI><B>Memory allocation routines have been modified</B>: <CODE>operator</CODE> <CODE><NOBR>new[]</NOBR></CODE> and <CODE>operator</CODE> <CODE><NOBR>delete[]</NOBR></CODE> have been added, the operators <CODE>new</CODE>/<CODE><NOBR>new[]</NOBR></CODE> now throw an exception if memory can't be allocated, and there are now alternative versions of the operators <CODE>new</CODE>/<CODE><NOBR>new[]</NOBR></CODE> that return 0 when an allocation fails (see <a href="../EC/EI7_FR.HTM#1894" TARGET="_top">Item E7</A>).<SCRIPT>create_link(8);</SCRIPT>
<A NAME="47015"></A>
<A NAME="dingp9"></A><LI><A NAME="p278"></A><B>New casting forms have been added</B>: <CODE>static_cast</CODE>, <CODE>dynamic_cast</CODE>, <CODE>const_cast</CODE>, and <CODE>reinterpret_cast</CODE>.<SCRIPT>create_link(9);</SCRIPT>
<A NAME="47020"></A>
<A NAME="dingp10"></A><LI><B>Language rules have been refined</B>: redefinitions of virtual functions need no longer have a return type that exactly matches that of the function they redefine, and the lifetime of temporary objects has been defined precisely.<SCRIPT>create_link(10);</SCRIPT>
</UL>
<A NAME="47024"></A>
<P><A NAME="dingp11"></A>
Almost all these changes are described in <NOBR><FONT COLOR="#FF0000" SIZE="-2"><B>°</B></FONT><A HREF="http://www.awl.com/cseng/cgi-bin/cdquery.pl?name=desec" onMouseOver="self.status='The Design and Evolution of C++ Home Page'; return true" onMouseOut="self.status = self.defaultStatus" target="_top"><I>The</NOBR> Design and Evolution of C++</I></A> (see <a href="./MIREADFR.HTM#p285" TARGET="_top">page 285</A>). Current C++ textbooks (those written after 1994) should include them, too. (If you find one that doesn't, reject it.) In addition, <I>More Effective C++</I> (that's this book) contains examples of how to use most of these new features. If you're curious about something on this list, try looking it up in <A HREF="../BOOKINDX/INDEX.HTM" TARGET="_top">the index</A>.<SCRIPT>create_link(11);</SCRIPT>
</P><A NAME="47078"></A>
<P><A NAME="dingp12"></A>
The changes to C++ proper pale in comparison to what's happened to the standard library. Furthermore, the evolution of the standard library has not been as well publicized as that of the language. <I>The Design and Evolution of C++</I>, for example, makes almost no mention of the standard library. The books that do discuss the library are sometimes out of date, because the library changed quite substantially in <NOBR>1994.<SCRIPT>create_link(12);</SCRIPT>
</NOBR></P><A NAME="47136"></A>
<P><A NAME="dingp13"></A>
The capabilities of the standard library can be broken down into the following general categories (see also <a href="../EC/EI49_FR.HTM#8392" TARGET="_top">Item E49</A>):<SCRIPT>create_link(13);</SCRIPT>
</P>
<A NAME="47146"></A>
<UL><A NAME="dingp14"></A><LI><B>Support for the standard C library.</B> Fear not, C++ still remembers its roots. Some minor tweaks have brought the C++ version of the C library into conformance with C++'s stricter type checking, but for all intents and purposes, everything you know and love (or hate) about the C library continues to be knowable and lovable (or hateable) in C++, too.<SCRIPT>create_link(14);</SCRIPT>
<A NAME="47149"></A>
<A NAME="dingp15"></A><LI><B>Support for strings.</B> As Chair of the working group for the standard C++ library, Mike Vilot was told, "If there isn't a standard <CODE>string</CODE> type, there will be blood in the streets!" (Some people get so emotional.) Calm yourself and put away those hatchets and truncheons — the standard C++ library has strings.<SCRIPT>create_link(15);</SCRIPT>
<A NAME="47254"></A>
<A NAME="dingp16"></A><LI><B>Support for localization.</B> Different cultures use different character sets and follow different conventions when displaying dates and times, sorting strings, printing monetary values, etc. Localization support within the standard library facilitates the development of programs that accommodate such cultural differences.<SCRIPT>create_link(16);</SCRIPT>
<A NAME="47237"></A>
<A NAME="dingp17"></A><LI><B>Support for I/O.</B> The iostream library remains part of the C++ standard, but the committee has tinkered with it a bit. Though some classes have been eliminated (notably <CODE>iostream</CODE> and <CODE>fstream</CODE>) and some have been replaced (e.g., <CODE>string</CODE>-based <A NAME="p279"></A><CODE>stringstream</CODE>s replace <CODE>char*</CODE>-based <CODE>strstream</CODE>s, which are now deprecated), the basic capabilities of the standard iostream classes mirror those of the implementations that have existed for several years.<SCRIPT>create_link(17);</SCRIPT>
<A NAME="47242"></A>
<A NAME="dingp18"></A><LI><B>Support for numeric applications.</B> Complex numbers, long a mainstay of examples in C++ texts, have finally been enshrined in the standard library. In addition, the library contains special array classes (<CODE>valarray</CODE>s) that restrict aliasing. These arrays are eligible for more aggressive optimization than are built-in arrays, especially on multiprocessing architectures. The library also provides a few commonly useful numeric functions, including partial sum and adjacent difference.<SCRIPT>create_link(18);</SCRIPT>
<A NAME="47243"></A>
<A NAME="dingp19"></A><LI><B>Support for general-purpose containers and algorithms.</B> Contained within the standard C++ library is a set of class and function templates collectively known as the Standard Template Library (STL). The STL is the most revolutionary part of the standard C++ library. I summarize its features below.<SCRIPT>create_link(19);</SCRIPT>
</UL>
<P><A NAME="dingp20"></A>
Before I describe the STL, though, I must dispense with two idiosyncrasies of the standard C++ library you need to know <NOBR>about.<SCRIPT>create_link(20);</SCRIPT>
</NOBR></P><A NAME="47608"></A>
<P><A NAME="dingp21"></A>
First, almost everything in the library is a <I>template</I>. In this book, I may have referred to the standard <CODE>string</CODE> class, but in fact there is no such class. Instead, there is a class template called <CODE>basic_string</CODE> that represents sequences of characters, and this template takes as a parameter the type of the characters making up the sequences. This allows for strings to be made up of <CODE>char</CODE>s, wide chars, Unicode chars, <NOBR>whatever.<SCRIPT>create_link(21);</SCRIPT>
</NOBR></P><A NAME="47636"></A>
<P><A NAME="dingp22"></A>
What we normally think of as the <CODE>string</CODE> class is really the template instantiation <CODE>basic_string<char></CODE>. Because its use is so common, the standard library provides a <NOBR>typedef:<SCRIPT>create_link(22);</SCRIPT>
</NOBR></P>
<A NAME="47627"></A>
<UL><PRE>typedef basic_string<char> string;
</PRE>
</UL><A NAME="47632"></A>
<P><A NAME="dingp23"></A>
Even this glosses over many details, because the <CODE>basic_string</CODE> template takes three arguments; all but the first have default values. To <I>really</I> understand the <CODE>string</CODE> type, you must face this full, unexpurgated declaration of <CODE>basic_string</CODE>:<SCRIPT>create_link(23);</SCRIPT>
</P>
<A NAME="47647"></A>
<UL><PRE>template<class charT,
class traits = string_char_traits<charT>,
class Allocator = allocator>
class basic_string;
</PRE>
</UL><A NAME="47645"></A>
<P><A NAME="dingp24"></A>
You don't need to understand this gobbledygook to use the <CODE>string</CODE> type, because even though <CODE>string</CODE> is a typedef for The Template Instantiation from Hell, it behaves as if it were the unassuming non-tem<A NAME="p280"></A>plate class the typedef makes it appear to be. Just tuck away in the back of your mind the fact that if you ever need to customize the types of characters that go into strings, or if you want to fine-tune the behavior of those characters, or if you want to seize control over the way memory for strings is allocated, the <CODE>basic_string</CODE> template allows you to do these <NOBR>things.<SCRIPT>create_link(24);</SCRIPT>
</NOBR></P><A NAME="47680"></A>
<P><A NAME="dingp25"></A>
The approach taken in the design of the <CODE>string</CODE> type — generalize it and make the generalization a template — is repeated throughout the standard C++ library. IOstreams? They're templates; a type parameter defines the type of character making up the streams. Complex numbers? Also templates; a type parameter defines how the components of the numbers should be stored. Valarrays? Templates; a type parameter specifies what's in each array. And of course the STL consists almost entirely of templates. If you are not comfortable with templates, now would be an excellent time to start making serious headway toward that <NOBR>goal.<SCRIPT>create_link(25);</SCRIPT>
</NOBR></P><A NAME="47601"></A>
<P><A NAME="dingp26"></A>
The other thing to know about the standard library is that virtually everything it contains is inside the namespace <CODE>std</CODE>. To use things in the standard library without explicitly qualifying their names, you'll have to employ a <CODE>using</CODE> directive or (preferably) <CODE>using</CODE> declarations (see <a href="../EC/EI28_FR.HTM#6429" TARGET="_top">Item E28</A>). Fortunately, this syntactic administrivia is automatically taken care of when you <CODE>#include</CODE> the appropriate <NOBR>headers.<SCRIPT>create_link(26);</SCRIPT>
</NOBR></P>
<P><A NAME="dingp27"></A><font ID="mhtitle">The Standard Template Library</font><SCRIPT>create_link(27);</SCRIPT>
</P>
<A NAME="86197"></A>
<P><A NAME="dingp28"></A>
The biggest news in the standard C++ library is the STL, the Standard Template Library. (Since almost everything in the C++ library is a template, the name STL is not particularly descriptive. Nevertheless, this is the name of the containers and algorithms portion of the library, so good name or bad, this is what we <NOBR>use.)<SCRIPT>create_link(28);</SCRIPT>
</NOBR></P><A NAME="86198"></A>
<P><A NAME="dingp29"></A>
The STL is likely to influence the organization of many — perhaps most — C++ libraries, so it's important that you be familiar with its general principles. They are not difficult to understand. The STL is based on three fundamental concepts: containers, iterators, and algorithms. Containers hold collections of objects. Iterators are pointer-like objects that let you walk through STL containers just as you'd use pointers to walk through built-in arrays. Algorithms are functions that work on STL containers and that use iterators to help them do their <NOBR>work.<SCRIPT>create_link(29);</SCRIPT>
</NOBR></P><A NAME="47916"></A>
<P><A NAME="dingp30"></A>
It is easiest to understand the STL view of the world if we remind ourselves of the C++ (and C) rules for arrays. There is really only one rule we need to know: a pointer to an array can legitimately point to any element of the array <I>or to one element beyond the end of the array</I>. If the pointer points to the element beyond the end of the array, it can be <A NAME="p281"></A>compared only to other pointers to the array; the results of dereferencing it are <NOBR>undefined.<SCRIPT>create_link(30);</SCRIPT>
</NOBR></P><A NAME="47931"></A>
<P><A NAME="dingp31"></A>
We can take advantage of this rule to write a function to find a particular value in an array. For an array of integers, our function might look like <NOBR>this:<SCRIPT>create_link(31);</SCRIPT>
</NOBR></P>
<A NAME="47940"></A>
<UL><PRE>int * find(int *begin, int *end, int value)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -