📄 index.html
字号:
<p>A <i>function </i><tt>try</tt><i> block</i> is a function whose body consists
of a <tt>try</tt> block and its associated handlers. A function <tt>try</tt>
block enables you to catch exceptions that might be thrown by a base class
constructor or by a constructor of a member object. The original specification
of exception handling did not enable users to handle exceptions thrown from
a constructor or a member initialization list locally; a function <tt>try</tt>
block fixes this loophole. Following is an example of a function <tt>try</tt>
block:</p>
<pre>
<tt>class Err{}; </tt>
<tt>A::A(const string& s) throw (Err); //allowed to throw only </tt>
<tt> //an exception of type Err</tt>
<tt> try</tt>
<tt> : str(s) //str's constructor might throw a bad_alloc </tt>
<tt> //exception, which violates C's exception specification</tt>
<tt> {</tt>
<tt> // constructor function body</tt>
<tt> }</tt>
<tt> catch (...) //we get here when an exception is thrown</tt>
<tt> //during the construction of str or C</tt>
<tt> {</tt>
<tt> throw Err(); //replace bad_alloc exception with an Err exception</tt>
<tt> }</tt>
</pre>
<h3> <a name="Heading18">Memory Management</a></h3>
<p>The Standard now defines three different versions of operator <tt>new</tt>:
plain <tt>new</tt>, <tt>nothrow new</tt>, and placement <tt>new</tt>. Each
of these operators has an array version as well. The Standard also defines
six matching types of operator <tt>delete</tt> that correspond the specific
versions of <tt>new</tt>. Memory management and the recently added versions
of <tt>new</tt> and <tt>delete</tt> are discussed in further detail in Chapter
11, "Memory Management."</p>
<h4> Operator new Throws an Exception in Case of a Failure</h4>
<p>In earlier stages of C++, operator <tt>new</tt> returned a <tt>NULL</tt>
pointer when it failed to allocate the requested amount of memory. The C++
standardization committee changed the specification of operator <tt>new</tt>
so that it throws an exception of type <tt>std::bad_alloc</tt>, rather than
returning a <tt>NULL</tt> pointer, when it fails. A program that uses operator
<tt>new</tt> directly or indirectly has to handle a potential <tt>std::bad_alloc</tt>
exception. For example</p>
<pre>
<tt>void f(int size) //standard-conforming usage of operator new</tt>
<tt>{</tt>
<tt> char *p = new char [size];</tt>
<tt> //...use p safely</tt>
<tt> delete [] p;</tt>
<tt> return;</tt>
<tt>}</tt>
<tt>#include <stdexcept></tt>
<tt>#include <iostream></tt>
<tt>using namespace std;</tt>
<tt>const int BUF_SIZE = 1048576L;</tt>
<tt>int main()</tt>
<tt>{</tt>
<tt> try</tt>
<tt> {</tt>
<tt> f(BUF_SIZE);</tt>
<tt> }</tt>
<tt> catch(bad_alloc& ex) //handle exception thrown from f()</tt>
<tt> {</tt>
<tt> cout<<ex.what()<<endl;</tt>
<tt> //...other diagnostics and remedies</tt>
<tt> }</tt>
<tt> return -1;</tt>
<tt>}</tt>
</pre>
<h4> nothrow new</h4>
<p>The Standard also defines an exception-free version of operator <tt>new</tt>,
which returns a <tt>NULL</tt> pointer in case of a failure rather than throwing
an exception. This version of <tt>new</tt> takes an additional argument
named <tt>nothrow</tt>. For example</p>
<pre>
<tt>#include <new></tt>
<tt>#include <string></tt>
<tt>using namespace std;</tt>
<tt>void f(int size) // demonstrating nothrow new</tt>
<tt>{</tt>
<tt> char *p = new (nothrow) char [size]; //array nothrow new</tt>
<tt> if (p == 0)</tt>
<tt> {</tt>
<tt> //...use p</tt>
<tt> delete [] p;</tt>
<tt> }</tt>
<tt> string *pstr = new (nothrow) string; //plain nothrow new</tt>
<tt> if (pstr == 0)</tt>
<tt> {</tt>
<tt> //...use pstr</tt>
<tt> delete [] pstr;</tt>
<tt> }</tt>
<tt> return;</tt>
<tt>}</tt>
</pre>
<h4> Placement new</h4>
<p>An additional version of operator <tt>new</tt> enables the user to construct
an object at a predetermined memory position. This version is called placement
<tt>new</tt>. Following is an example of using placement <tt>new</tt>:</p>
<pre>
<tt>#include <new></tt>
<tt>#include <iostream></tt>
<tt>using namespace std;</tt>
<tt>void placement()</tt>
<tt>{</tt>
<tt> int *pi = new int; //plain new</tt>
<tt> int *p = new (pi) int (5); //placement new</tt>
<tt> //...use p</tt>
<tt> delete pi;</tt>
<tt>}</tt>
</pre>
<h3> <a name="Heading19">Constructors and Destructors</a></h3>
<p>Fundamental types can be initialized by a special constructor. In addition,
the Standard also defines a pseudo destructor for each of these types (see
Chapter 4, "Special Member Functions: Default Constructor, Copy Constructor,
Destructor, and Assignment Operator").</p>
<h4> Constructors of Fundamental Types</h4>
<p>Variables of fundamental types can be initialized by invoking their constructor
explicitly. For example</p>
<pre>
<tt>void f()</tt>
<tt>{</tt>
<tt> int n = int(); // zero initialized</tt>
<tt> char c = char(); // also zero initialized</tt>
<tt> double d = double(0.5); //other initializers are allowed</tt>
<tt>}</tt>
</pre>
<p>This language extension enables uniform treatment in templates for fundamental
types and user-defined types.</p>
<h4> Explicit Constructors</h4>
<p>A constructor that takes a single argument is, by default, an implicit
conversion operator that converts its argument to an object of its class.
In order to avoid such implicit conversions, a constructor that takes one
argument can be declared <tt>explicit</tt>. For example</p>
<pre>
<tt>class C</tt>
<tt>{</tt>
<tt>public:</tt>
<tt> explicit C(int size); // disallow implicit conversion</tt>
<tt>};</tt>
</pre>
<h4> Pseudo Destructors</h4>
<p>A <i>pseudo destructor</i> is a syntactic construct whose sole purpose
is to satisfy the need for generic algorithms and containers. It is a no-op
code, and has no real effect on its object. For example</p>
<pre>
<tt>typedef int N;</tt>
<tt>void f()</tt>
<tt>{</tt>
<tt> N i = 0;</tt>
<tt> i.N::~N(); // pseudo destructor invocation</tt>
<tt> i = 1; // i was not affected by the invocation of the pseudo destructor</tt>
<tt>}</tt>
</pre>
<h3> <a name="Heading20">Local Definitions and Scoping Rules</a></h3>
<p>The scoping rules for a variable that is defined in a <tt>for</tt> statement
were changed. Additionally, it is now possible to define and initialize
variables inside an <tt>if</tt> condition.</p>
<h4> The Scope of a Local Loop Counter</h4>
<p>C++ allows declaration of variables wherever they are needed, enabling
immediate initializations. A good example is a loop counter, which can be
declared inside a <tt>for</tt> statement. For example</p>
<pre>
<tt>void f()</tt>
<tt>{</tt>
<tt> for (int i = 0; i < 10; i++) // i declared and initialized </tt>
<tt> // inside a for-statement</tt>
<tt> {</tt>
<tt> cout << i <<endl; //output 0 to 9</tt>
<tt> }</tt>
<tt> int n = i; //compilation error, i not in scope</tt>
<tt>}</tt>
</pre>
<p>In earlier stages of C++, a local variable declared in this way remained
accessible in its enclosing block. This was a source for bugs and name hiding.
Consequently, the standard has been revised to fix this loophole, so to
speak; local variables that are created this way are inaccessible outside
their <tt>for</tt> statement. In the preceding example, the variable <tt>i</tt>
goes out of scope when the loop is exited.</p>
<h4> Declaring Variables Inside an if Condition</h4>
<p>You can define and initialize a variable inside the condition of an <tt>if</tt>
statement. For example</p>
<pre>
<tt>class Base {/*..*/};</tt>
<tt>class Derived: public Base {/*..*/};</tt>
<tt>void func (Base& b)</tt>
<tt>{</tt>
<tt> if ( Derived *pd = dynamic_cast < Derived* > (&b) ) //declaration </tt>
<tt> // inside an if-condition</tt>
<tt> {</tt>
<tt> //dynamic_cast was successful; use pd here</tt>
<tt> return;</tt>
<tt> }//pd goes out of scope at this point</tt>
<tt> //otherwise dynamic_cast failed; variable pd is not in scope</tt>
<tt>}</tt>
</pre>
<p>The advantage of declaring the pointer <tt>pd</tt> locally is obvious:
It is always initialized with an appropriate value, and it isn't visible
to other parts of the program that are not to use it (see Chapter 12, "Optimizing
Your Code").</p>
<h3> <a name="Heading21">Namespaces</a></h3>
<p><i>Namespaces</i> were the latest feature to be added to the language.
Namespaces are used to prevent name conflicts and to facilitate configuration
management and version control in large-scale projects. Most of the components
of the Standard Library are grouped under namespace <tt>std</tt>. There
are three methods for injecting namespace members into a scope: a <tt>using</tt>
directive, a <tt>using</tt> declaration, or a fully qualified name. Argument-dependent
lookup, or Koenig lookup, simplifies the use of namespaces by automating
the name lookup process. Namespaces are discussed in more detail in Chapter
8, "Namespaces." </p>
<h3> <a name="Heading22">Templates</a></h3>
<p>A <i>template</i> is a mold from which related functions or classes are
instantiated. Templates have come a long way since they were first introduced
to the language in 1991. Back then, they were merely clever macros. However,
the adoption of STL required considerable extensions to this feature. An
overview of these extension is provided in the following sections. Templates
are discussed in detail in Chapter 9, "Templates."</p>
<h4> Template-Template Argument</h4>
<p>A template can now take a template as an argument. For example</p>
<pre>
<tt>int send(const std::vector<char*>& );</tt>
<tt>int main()</tt>
<tt>{</tt>
<tt> std::vector <std::vector<char*> > msg_que(10);</tt>
<tt> //...fill msg_que</tt>
<tt> for (int i =0; i < 10; i++) //transmit messages</tt>
<tt> send(msg_que[i]);</tt>
<tt> return 0;</tt>
<tt>}</tt>
</pre>
<h4> Default Type Arguments</h4>
<p>Templates can have default type arguments. For example</p>
<pre>
<tt>template <class T, class S = size_t > class C //using a default type</tt>
<tt>{/**/};</tt>
</pre>
<h4> Member Templates</h4>
<p>Templates can be nested; a template can be declared within another class
or a class template. Such a template is called a <i>member template</i>.
Following is an example:</p>
<pre>
<tt>template<class T> class C</tt>
<tt>{</tt>
<tt>public:</tt>
<tt> template<class T2> int func(const T2&); //declaration of a member template</tt>
<tt> //...</tt>
<tt>};</tt>
<tt>template<class T> template<class T2> int C<T>::func(const T2& s) // definition</tt>
<tt>{</tt>
<tt> //...</tt>
<tt>}</tt>
</pre>
<h4> The typename Keyword</h4>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -