📄 ch02.htm
字号:
a template separately and then use its declaration, the template has to be <i>exported</i>. This is done by preceding the template's definition with the keyword <tt>export</tt>.</p> <h3> <a name="Heading23">The Standard Template Library</a></h3> <p>According to Bjarne Stroustrup, the most important change in C++ since 1991 is not a language change; it is the addition of the standard library. The <i>Standard Template Library</i>, or <i>STL</i>, comprises a substantial part of the Standard Library. STL is collection of generic containers -- such as vector, list, and stack -- and a rich collection of generic algorithms for sorting, finding, merging, and transforming these containers. Chapter 10, "STL and Generic Programming," is dedicated to STL.</p> <h3> <a name="Heading24">Internationalization and Localization</a></h3> <p>The current C++ Standard is an international Standard approved by ISO. To qualify as such, Standard C++ has been fully internationalized. Internationalization consists of several modifications and extensions. These include the addition of the keyword <tt>wchar_t</tt> (<tt>wchar_t</tt> was already defined in ISO C as a <tt>typedef</tt> but it wasn't a reserved keyword). In addition, the standard stream and string classes have been templatized to support both narrow and wide characters. Finally, the <tt><locale></tt> library defines template classes and declares functions that encapsulate and manipulate locale-related information such as monetary, numeric, and time conventions. The locale feature sets are encapsulated in classes (or <i>facets</i>) that the users can extend. </p> <h4> Wide Character Streams</h4> <p>C++ provides four standard I/O streams that are automatically instantiated before a program's outset. They are defined in the header <tt><iostream></tt>:</p> <pre><tt>cin // standard input stream of char</tt><tt>cout // standard output stream of char</tt><tt>cerr // standard unbuffered output stream for error messages</tt><tt>clog // standard output stream for error messages</tt></pre> <p>Each of these four streams now has a corresponding wide-character version:</p> <pre><tt>wcin</tt><tt>wcout</tt><tt>wcerr</tt><tt>wclog</tt></pre> <h3> <a name="Heading25">Miscellaneous</a></h3> <p>Two additional extensions were recently added to the Standard: the initialization of <tt>const static</tt> data members inside the class body and the <tt>mutable</tt> storage specifier. Both of these extensions are discussed in the following sections.</p> <h4> Initialization of const static Data Members</h4> <p><tt>const static</tt> data members of an integral type can now be initialized inside their class. In this case, the initialization is also a definition, so no further definitions are required outside the class body. For example</p> <pre><tt>#include <string></tt><tt>class Buff</tt><tt>{</tt><tt>private:</tt><tt> static const int MAX = 512; // initialization +definition</tt><tt> static const char flag = 'a'; // initialization +definition</tt><tt> static const std::string msg; //non-integral type; must be defined outside</tt><tt> //the class body</tt><tt> //..</tt><tt>};</tt><tt>const std::string Buff::msg = "hello";</tt></pre> <h4> A mutable Object Member</h4> <p>A <tt>const</tt> member function cannot modify the state of its object. However, auxiliary data members (flags, reference counters) sometimes have to be modified by a <tt>const</tt> member function. Such data members can be declared <tt>mutable</tt>. A <tt>mutable</tt> member is never <tt>const</tt>, even if its object is <tt>const</tt>; therefore, it can be modified by a <tt>const</tt> member function. The following example demonstrates the use of this feature:</p> <pre><tt>class Buffer</tt><tt>{</tt><tt>private:</tt><tt> void * data; //raw data buffer to be transmitted on some network</tt><tt> size_t size;</tt><tt> mutable int crc;//used to verify that no errors occurred during transmission</tt><tt>public:</tt><tt> int GetCrc() const;</tt><tt> void Transmit() const; //computation of crc is done here</tt><tt>};</tt><tt>void f()</tt><tt>{</tt><tt> Buffer buffer;</tt><tt> //...fill buffer with data</tt><tt> buffer.Transmit(); //crc can be modified here; non-mutable members may not</tt><tt>}</tt></pre> <p>There is no point in calculating the <tt>crc</tt> value every time a few more bytes are appended to <tt>buffer</tt>. Instead, it is computed by the member function <tt>Transmit()</tt> right before <tt>buffer</tt> is sent. However, <tt>Transmit()</tt> is not supposed to modify its object's state so that it is declared as a <tt>const</tt> member function. In order to allow assignment of the correct <tt>crc</tt> value, the data member <tt>crc</tt> is declared <tt>mutable</tt>; hence, it can be modified by a <tt>const</tt> member function.</p> <h2> <a name="Heading26">Deprecated Feature</a></h2> <p>A <i>deprecated feature</i> is one that the current edition of the Standard regards as normative, but that is not guaranteed to be part of the Standard in future revisions. Again, this is somewhat understating the intent of this definition. One of the consequences of the evolution and standardization of a programming language is the gradual removal of undesirable, dangerous, or redundant features and constructs. By deprecating a feature, the standardization committee expresses the desire to have the feature removed from the language. Removing it from the language altogether is impractical because existing code will not compile anymore. The deprecation gives the user sufficient time to replace a deprecated feature with a Standard-endorsed feature. The Standard lists the features that are discussed in the following sections as deprecated.</p> <h3> <a name="Heading27">Use of an Operand of Type bool with the Postfix ++ Operator</a></h3> <p>Applying postfix <tt>++</tt> to a variable of type <tt>bool</tt> is still allowed for backward compatibility with old code that uses plain <tt>int</tt> or some <tt>typedef</tt>, as in</p> <pre><tt> bool done = false;</tt><tt> while(!done)</tt><tt> {</tt><tt> if(condition)</tt><tt> //...do something</tt><tt> else done++; //deprecated</tt><tt> }</tt></pre> <p>Incrementing a <tt>bool</tt> always yields <tt>true</tt>, regardless of the original value. However, this practice is deprecated; therefore, it might not be supported in the future. Remember that applying <tt>--</tt> (decrement operator) to a <tt>bool</tt> variable is illegal.</p> <h3> <a name="Heading28">Use of static to Declare Objects in Namespace Scope</a></h3> <p>The use of the keyword <tt>static</tt> to declare a function or an object local to a translation unit is deprecated. Instead, use an <i>unnamed namespace</i> for that purpose (more on this in Chapter 8).</p> <h3> <a name="Heading29">Access Declarations</a></h3> <p>The access of a member of a base class can be changed in a derived class by an <i>access declaration</i>. For example</p> <pre><tt>class A</tt><tt>{</tt><tt>public:</tt><tt> int k;</tt><tt> int l;</tt><tt>};</tt><tt>class D : public A</tt><tt>{</tt><tt>private:</tt><tt> A::l; // access declaration changes access of A::l to private; deprecated</tt><tt>};</tt></pre> <p>The use of access declarations is deprecated. Use a <tt>using</tt><i> declaration</i> instead:</p> <pre><tt>class D : public A // using-declaration version</tt><tt>{</tt><tt>private:</tt><tt> using A::l; // using declaration changes the access of A::l to private</tt><tt>};</tt><tt>void func()</tt><tt>{</tt><tt> D d;</tt><tt> d.l = 0; //error; cannot access private member</tt><tt>}</tt></pre> <h3> <a name="Heading30">Implicit Conversion from const to non-const Qualification for String Literals</a></h3> <p>A string literal can be implicitly converted from type pointer to <tt>const char</tt> to type <tt>pointer to char</tt>. Similarly, a wide string literal can be implicitly converted from type pointer to <tt>const wchar_t</tt> to pointer to <tt>wchar_t</tt>. For example</p> <pre><tt>char *s = "abc"; //string literal implicitly converted to non-const; deprecated</tt></pre> <p>The type of the literal <tt>"abc"</tt> is <tt>const char[]</tt>, but <tt>s</tt> is a pointer to non-<tt>const char</tt>. Such implicit conversions from <tt>const</tt> to non-<tt>const</tt> qualifications for string literals are deprecated because they might lead to the following erroneous code:</p> <pre><tt>strcpy(s, "cde"); //undefined behavior</tt></pre> <p>The preferred form is</p> <pre><tt>const char *s = "abc"; //OK</tt></pre> <h3> <a name="Heading31">Standard C Headers in the form <name.h></a></h3> <p>For compatibility with the Standard C library, C++ still supports the naming convention of C headers in the form <tt><xxx.h></tt> -- but this naming convention is now deprecated (this is discussed in more detail in Chapter 8). For example</p> <pre><tt>#include <stdlib.h> //deprecated</tt></pre> <p>Use the newer naming convention, <tt><cxxx></tt>, instead:</p> <pre><tt>#include <cstdlib> //OK, 'c' prefixed and ".h" omitted</tt></pre> <p>The reason for this is that <tt>".h"</tt> headers inject all their names into the global namespace, whereas the newer convention headers, <tt><cname></tt>, keep their names in namespace <tt>std</tt>.</p> <h3> <a name="Heading32">Implicit int Declarations</a></h3> <p>The default type for missing declarations such as the following is <tt>int</tt>:</p> <pre><tt>static k =0; //'int' type deduced; deprecated</tt><tt>const c =0; //'int' type deduced; deprecated</tt></pre> <p>This convention is now considered deprecated. Instead, use explicit type names:</p> <pre><tt>static int k =5;</tt><tt>const int c = 0;</tt></pre> <h3> <a name="Heading33">Other Deprecated Features</a></h3> <p>The Standard deprecates some of the members of old <tt>iostream</tt> classes (article 4.6). In addition, it deprecates three types in the header <tt><strstream></tt> that associate stream buffers with character array objects (article 4.7).</p> <p>From a user's point of view, deprecated features are not to be used in new code because future versions of the language will flag it as an error. In the interim period, compilers can issue a warning about its use.</p> <h2> <a name="Heading34">Conclusions</a></h2> <p>As you have seen, standard C++ is quite different from what it used to be four, five, or ten years ago. Many of the changes and modifications have been initiated by software vendors (the <tt>bool</tt> data type, for instance). Others have been initiated by the Standardization committee (for example, the new cast operators and STL). During the hectic standardization process, complaints about "randomly accepted changes" on the one hand, and "missing features" on the other hand, were often heard. However, the Standardization committee has been very thoughtful and prudent in selecting these extensions and modifications. Fortunately, the approval of the Standard by ISO in 1998 ensures its stability for at least five years. This freeze period enables both compiler vendors and language users to digest the current Standard and use it effectively. In doing so, one usually finds that C++ is better today than it ever was. </p> <p> </p> </div></CENTER><CENTER><P><HR> <A HREF="/publishers/que/series/professional/0789720221/index.htm"><img src="/publishers/que/series/professional/0789720221/button/contents.gif" WIDTH="128"HEIGHT="28" ALIGN="BOTTOM" ALT="Contents" BORDER="0"></A> <BR><BR><BR><p></P><P>© <A HREF="/publishers/que/series/professional/0789720221/copy.htm">Copyright 1999</A>, Macmillan Computer Publishing. Allrights reserved.</p></CENTER></BODY></HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -