[ Pobierz całość w formacie PDF ]
cout
}
template void g(T* p) {
p->template f();
p->template f();
typename T::template S s; // use of scope operator on a member template
s.h();
}
int main()
{
X temp;
g(&temp);
}
The following is the output of the above example:
Chapter 16. Templates 315
Primary: 100
Specialized, non-type argument = 20
member template's member function: 40
If you do not use the keyword template in these cases, the compiler will interpret
the
p->f();
The compiler interpretsfas a non-template member, and the
operator.
v Chapter 16. Templates on page 283
316 C/C++ Language Reference
Chapter 17. Exception Handling
Exception handling is a mechanism that separates code that detects and
handles exceptional circumstances from the rest of your program. Note that an
exceptional circumstance is not necessarily an error.
When a function detects an exceptional situation, you represent this with an object.
This object is called an exception object. In order to deal with the exceptional
situation you throw the exception. This passes control, as well as the exception, to a
designated block of code in a direct or indirect caller of the function that threw the
exception. This block of code is called a handler. In a handler, you specify the types
of exceptions that it may process. The C++ runtime, together with the generated
code, will pass control to the first appropriate handler that is able to process the
the exception thrown. When this happens, an exception is caught. A handler may
rethrow an exception so it can be caught by another handler.
The exception handling mechanism is made up of the following elements:
v try blocks: a block of code that may throw an exception that you want to handle
with special processing
v catch blocks or handlers: a block of code that is executed when a try block
encounters an exception
v throw expression: indicates when your program encounters an exception
v exception specifications: specify which exceptions (if any) a function may throw
v unexpected() function: called when a function throws an exception not specified
by an exception specification
v terminate() function: called for exceptions that are not caught
Syntax try Block
try { statements } handler
Syntax Function try Block
try function_body handler
: member_initializer_list
Syntax Exception Handler or catch Block
catch ( exception_declaration ) { statements }
Syntax throw Expression
© Copyright IBM Corp. 1998, 2001 317
throw
assignment_expression
v The try Keyword
v catch Blocks on page 320
v The throw Expression on page 326
v Exception Specifications on page 329
v unexpected() on page 332
v terminate() on page 333
The try Keyword
You use a try block to indicate which areas in your program that might
throw exceptions you want to handle immediately. You use a function try block to
indicate that you want to detect exceptions in the entire body of a function.
Syntax try Block
try { statements } handler
Syntax Function try Block
try function_body handler
: member_initializer_list
The following is an example of a function try block with a member initializer, a
function try block and a try block:
#include
using namespace std;
class E {
public:
const char* error;
E(const char* arg) : error(arg) { }
};
class A {
public:
int i;
// A function try block with a member
// initializer
A() try : i(0) {
throw E("Exception thrown in A()");
}
catch (E& e) {
cout
}
318 C/C++ Language Reference
};
// A function try block
void f() try {
throw E("Exception thrown in f()");
}
catch (E& e) {
cout
}
void g() {
throw E("Exception thrown in g()");
}
int main() {
f();
// A try block
try {
g();
}
catch (E& e) {
cout
}
A x;
}
The following is the output of the above example:
Exception thrown in f()
Exception thrown in g()
Exception thrown in A()
The constructor of classAhas a function try block with a member initializer.
Functionf()has a function try block. Themain()function contains a try block.
v Initializing Base Classes and Members on page 262
Nested Try Blocks
When try blocks are nested and a throw occurs in a function called by an
inner try block, control is transferred outward through the nested try blocks until
the first catch block is found whose argument matches the argument of the throw
expression.
For example:
try
{
func1();
try
{
func2();
}
catch (spec_err) { /* ... */ }
func3();
}
catch (type_err) { /* ... */ }
// if no throw is issued, control resumes here.
In the above example, ifspec_erris thrown within the inner try block (in this case,
fromfunc2()), the exception is caught by the inner catch block, and, assuming this
Chapter 17. Exception Handling 319
catch block does not transfer control,func3()is called. Ifspec_erris thrown after
the inner try block (for instance, byfunc3()), it is not caught and the function
terminate() is called. If the exception thrown fromfunc2()in the inner try block is
type_err, the program skips out of both try blocks to the second catch block
without invokingfunc3(), because no appropriate catch block exists following the
inner try block.
You can also nest a try block within a catch block.
v terminate() on page 333
v unexpected() on page 332
v Special Exception Handling Functions on page 332
catch Blocks
The following is the syntax for an exception handler or a catch block:
catch ( exception_declaration ) { statements }
You can declare a handler to catch many types of exceptions. The allowable objects
that a function can catch are declared in the parentheses following the catch
keyword (the exception_declaration). You can catch objects of the fundamental types,
base and derived class objects, references, and pointers to all of these types. You
can also catch const and volatile types. The exception_declaration cannot be an
incomplete type, or a reference or pointer to an incomplete type other than one of
the following:
v void*
v const void*
v volatile void*
v const volatile void*
You cannot define a type in an exception_declaration.
You can also use the catch(...) form of the handler to catch all thrown exceptions
that have not been caught by a previous catch block. The ellipsis in the catch
argument indicates that any exception thrown can be handled by this handler.
If an exception is caught by a catch(...) block, there is no direct way to access the
object thrown. Information about an exception caught by catch(...) is very limited.
You can declare an optional variable name if you want to access the thrown object
in the catch block.
A catch block can only catch accessible objects. The object caught must have an
accessible copy constructor.
v volatile and const Qualifiers on page 50
v Member Access on page 223
320 C/C++ Language Reference
Function try block Handlers
The scope and lifetime of the parameters of a function or constructor
extend into the handlers of a function try block. The following example
demonstrates this:
void f(int &x) try {
throw 10;
}
catch (const int &i)
{
x = i;
}
int main() {
int v = 0;
f(v);
}
The value ofvafterf()is called is10.
A function try block on main() does not catch exceptions thrown in destructors of
objects with static storage duration, or constructors of namespace scope objects.
The following example throws an exception from a destructor of a static object:
#include
using namespace std;
class E {
public:
const char* error;
E(const char* arg) : error(arg) { }
};
class A {
public: xA() { throw E("Exception in xA()"); }
};
class B {
public: xB() { throw E("Exception in xB()"); }
};
int main() try {
cout
static A cow;
B bull;
}
catch (E& e) { [ Pobierz całość w formacie PDF ]
zanotowane.pl doc.pisz.pl pdf.pisz.pl freetocraft.keep.pl
cout
}
template void g(T* p) {
p->template f();
p->template f();
typename T::template S s; // use of scope operator on a member template
s.h();
}
int main()
{
X temp;
g(&temp);
}
The following is the output of the above example:
Chapter 16. Templates 315
Primary: 100
Specialized, non-type argument = 20
member template's member function: 40
If you do not use the keyword template in these cases, the compiler will interpret
the
p->f();
The compiler interpretsfas a non-template member, and the
operator.
v Chapter 16. Templates on page 283
316 C/C++ Language Reference
Chapter 17. Exception Handling
Exception handling is a mechanism that separates code that detects and
handles exceptional circumstances from the rest of your program. Note that an
exceptional circumstance is not necessarily an error.
When a function detects an exceptional situation, you represent this with an object.
This object is called an exception object. In order to deal with the exceptional
situation you throw the exception. This passes control, as well as the exception, to a
designated block of code in a direct or indirect caller of the function that threw the
exception. This block of code is called a handler. In a handler, you specify the types
of exceptions that it may process. The C++ runtime, together with the generated
code, will pass control to the first appropriate handler that is able to process the
the exception thrown. When this happens, an exception is caught. A handler may
rethrow an exception so it can be caught by another handler.
The exception handling mechanism is made up of the following elements:
v try blocks: a block of code that may throw an exception that you want to handle
with special processing
v catch blocks or handlers: a block of code that is executed when a try block
encounters an exception
v throw expression: indicates when your program encounters an exception
v exception specifications: specify which exceptions (if any) a function may throw
v unexpected() function: called when a function throws an exception not specified
by an exception specification
v terminate() function: called for exceptions that are not caught
Syntax try Block
try { statements } handler
Syntax Function try Block
try function_body handler
: member_initializer_list
Syntax Exception Handler or catch Block
catch ( exception_declaration ) { statements }
Syntax throw Expression
© Copyright IBM Corp. 1998, 2001 317
throw
assignment_expression
v The try Keyword
v catch Blocks on page 320
v The throw Expression on page 326
v Exception Specifications on page 329
v unexpected() on page 332
v terminate() on page 333
The try Keyword
You use a try block to indicate which areas in your program that might
throw exceptions you want to handle immediately. You use a function try block to
indicate that you want to detect exceptions in the entire body of a function.
Syntax try Block
try { statements } handler
Syntax Function try Block
try function_body handler
: member_initializer_list
The following is an example of a function try block with a member initializer, a
function try block and a try block:
#include
using namespace std;
class E {
public:
const char* error;
E(const char* arg) : error(arg) { }
};
class A {
public:
int i;
// A function try block with a member
// initializer
A() try : i(0) {
throw E("Exception thrown in A()");
}
catch (E& e) {
cout
}
318 C/C++ Language Reference
};
// A function try block
void f() try {
throw E("Exception thrown in f()");
}
catch (E& e) {
cout
}
void g() {
throw E("Exception thrown in g()");
}
int main() {
f();
// A try block
try {
g();
}
catch (E& e) {
cout
}
A x;
}
The following is the output of the above example:
Exception thrown in f()
Exception thrown in g()
Exception thrown in A()
The constructor of classAhas a function try block with a member initializer.
Functionf()has a function try block. Themain()function contains a try block.
v Initializing Base Classes and Members on page 262
Nested Try Blocks
When try blocks are nested and a throw occurs in a function called by an
inner try block, control is transferred outward through the nested try blocks until
the first catch block is found whose argument matches the argument of the throw
expression.
For example:
try
{
func1();
try
{
func2();
}
catch (spec_err) { /* ... */ }
func3();
}
catch (type_err) { /* ... */ }
// if no throw is issued, control resumes here.
In the above example, ifspec_erris thrown within the inner try block (in this case,
fromfunc2()), the exception is caught by the inner catch block, and, assuming this
Chapter 17. Exception Handling 319
catch block does not transfer control,func3()is called. Ifspec_erris thrown after
the inner try block (for instance, byfunc3()), it is not caught and the function
terminate() is called. If the exception thrown fromfunc2()in the inner try block is
type_err, the program skips out of both try blocks to the second catch block
without invokingfunc3(), because no appropriate catch block exists following the
inner try block.
You can also nest a try block within a catch block.
v terminate() on page 333
v unexpected() on page 332
v Special Exception Handling Functions on page 332
catch Blocks
The following is the syntax for an exception handler or a catch block:
catch ( exception_declaration ) { statements }
You can declare a handler to catch many types of exceptions. The allowable objects
that a function can catch are declared in the parentheses following the catch
keyword (the exception_declaration). You can catch objects of the fundamental types,
base and derived class objects, references, and pointers to all of these types. You
can also catch const and volatile types. The exception_declaration cannot be an
incomplete type, or a reference or pointer to an incomplete type other than one of
the following:
v void*
v const void*
v volatile void*
v const volatile void*
You cannot define a type in an exception_declaration.
You can also use the catch(...) form of the handler to catch all thrown exceptions
that have not been caught by a previous catch block. The ellipsis in the catch
argument indicates that any exception thrown can be handled by this handler.
If an exception is caught by a catch(...) block, there is no direct way to access the
object thrown. Information about an exception caught by catch(...) is very limited.
You can declare an optional variable name if you want to access the thrown object
in the catch block.
A catch block can only catch accessible objects. The object caught must have an
accessible copy constructor.
v volatile and const Qualifiers on page 50
v Member Access on page 223
320 C/C++ Language Reference
Function try block Handlers
The scope and lifetime of the parameters of a function or constructor
extend into the handlers of a function try block. The following example
demonstrates this:
void f(int &x) try {
throw 10;
}
catch (const int &i)
{
x = i;
}
int main() {
int v = 0;
f(v);
}
The value ofvafterf()is called is10.
A function try block on main() does not catch exceptions thrown in destructors of
objects with static storage duration, or constructors of namespace scope objects.
The following example throws an exception from a destructor of a static object:
#include
using namespace std;
class E {
public:
const char* error;
E(const char* arg) : error(arg) { }
};
class A {
public: xA() { throw E("Exception in xA()"); }
};
class B {
public: xB() { throw E("Exception in xB()"); }
};
int main() try {
cout
static A cow;
B bull;
}
catch (E& e) { [ Pobierz całość w formacie PDF ]