Exceptions
C. Papachristos
Robotic Workers Lab
University of Nevada, Reno
CS-202
Course , Projects , Labs:
Your 10th Project was due this Wednesday 4/29. � Your 11th Project is due next Friday after the Final, 5/8.
Your Final exam is next Thursday 5/7.
Monday | Tuesday | Wednesday | Thursday | Friday | | Sunday |
|
|
| Lab (8 Sections) |
| | |
| CLASS | PASS Session | CLASS |
| | |
PASS Session | | Project DEADLINE | LAST Project | PASS Session | | FINAL PASS Session |
Course Week
CS-202 C. Papachristos
Today’s Topics
CS-202 C. Papachristos
Separating Error–Detection & Error–Handling
C++ Exceptions
The try–catch Block – The throw Expression
Exception(s) from Functions
Exception Classes
Exception(s) from ctor(s) – Exception(s) from dtor(s)
Exceptions
CS-202 C. Papachristos
Common Runtime Errors
There can be a wide variety of Runtime Error “types” in a program
HugeDataStruct * hDS_array = new HugeDataStruct [HUGE_NUM];
std::vector<int> intVec(100, -1);
int intVal = intVec.at(100);
std::ifstream inFile;
inFile.exceptions ( std::ifstream::failbit | std:: ifstream::badbit );
inFile.open ("a_non_existent_file.txt");
Car myCar;
myCar.setLicensePlates("#$@&%*!");
Exceptions
CS-202 C. Papachristos
Error Handling
Common practices for error handling (so far)
cerr << "Not enough memory, allocation requires freeing resources";
cerr << "File not found or other error occurred, try again:";
cin >> inputFileName;
cerr << "License Plates cannot carry special characters, try again:";
cin >> licensePlatesString;
…
std::vector<int> intVec(100, -1);
cout << intVec[100];
Undefined Behavior:
Exceptions
CS-202 C. Papachristos
Error Handling
Errors are handled where they occur
Advantages:
Disadvantages:
Exceptions
CS-202 C. Papachristos
Error Handling
Using Functions/Classes & Handling Errors
Programmer #1 – The function / class Implementer:
Programmer #2 – The function / class User:
(Might not even be exposed to the fact that an error occurred.)
Exceptions
CS-202 C. Papachristos
Error Handling
Error–Detection & Error–Handling
Error–Detection:
Error–Handling:
Exceptions is a mechanism to separate�Error–Detection & Error–Handling.
Exceptions
CS-202 C. Papachristos
Error Handling
Error–Handling via Exceptional Cases
Exceptions are used to handle Errors as “Exceptional Cases”:
Exceptions allow separation of Error–Detection from Error–Handling:
C++ (unhandled) Exception example case – Vector out-of-bounds indexing:
std::vector<int> intVec(100, -1);
cout << intVec.at(100);
terminate called after throwing an instance of 'std::out_of_range' what(): vector::_M_range_check
Exceptions
CS-202 C. Papachristos
Exception(s) Implementation
The keywords try & catch
The try – catch Block:
To catch different object types, multiple catch statements are needed.
Exceptions
CS-202 C. Papachristos
Exception(s) Implementation
The keywords try & catch
The try – catch Block Syntax:
try {
/*a sequence of code statements that might work erroneously*/
}
catch (const int & err_code) {
/*code handling int object type*/
}
catch (const std::exception & ex) {
/*code handling std::exception object type*/
}
catch ( … ) {
/*code that is triggered by any object type*/
}
Try to run the code in this Block Scope, but an error condition might occur.
Exceptions
CS-202 C. Papachristos
Exception(s) Implementation
The keywords try & catch
The try – catch Block Syntax:
try {
/*a sequence of code statements that might work erroneously*/
}
catch (const int & err_code) {
/*code handling int object type*/
}
catch (const std::exception & ex) {
/*code handling std::exception object type*/
}
catch ( … ) {
/*code that is triggered by any object type*/
}
Just one, or multiple catch blocks to handle multiple Exception object types.
Exceptions
CS-202 C. Papachristos
Exception(s) Implementation
The keywords try & catch
The try – catch Block Syntax:
try {
/*a sequence of code statements that might work erroneously*/
}
catch (const int & err_code) {
/*code handling int object type*/
}
catch (const std::exception & ex) {
/*code handling std::exception object type*/
}
catch ( … ) {
/*code that is triggered by any object type*/
}
If within the code of the try Block an error is detected, and an int type Exception is produced, Error-handling based on this int will occur here.
The same process but for Exception Objects of std::exception type.
Generic Handler triggered by any Exception Object type.
Exceptions
CS-202 C. Papachristos
Exception(s) Implementation
The throw Expression
Exception Throwing is associated with Error–Detection. Flow Control passes over to Exception-Handling, alongside some type of Exception Object.
Exceptions
CS-202 C. Papachristos
Exception(s) Implementation
The throw Expression
Exception Throwing is associated with Error–Detection. Flow Control passes over to Exception-Handling, alongside some type of Exception Object.
Control Flow moves backwards and calls the Destructors of every object of� auto Storage-Duration that has been constructed, in reverse order of their completion.
Note : Not for objects Constructed by a new Expression (Dynamic Storage-Duration) !
Exceptions
CS-202 C. Papachristos
Exception(s) Implementation
The throw Expression
Exception Throwing is associated with Error–Detection. Flow Control passes over to Exception-Handling, alongside some type of Exception Object.
Control Flow moves backwards and calls the Destructors of every object of� auto Storage-Duration that has been constructed, in reverse order of their completion.
Sub–Note : � If the Exception is thrown from within a Constructor that was invoked� by a new Expression, the matching Deallocation Function is called, if available.
- i.e. operator delete ([])
Exceptions
CS-202 C. Papachristos
Exception(s) Implementation
The throw Expression
Exception Throwing is associated with Error–Detection. Flow Control passes over to Exception-Handling, alongside some type of Exception Object.
Control Flow moves backwards and calls the Destructors of every object of� auto Storage-Duration that has been constructed, in reverse order of their completion.
Note : Not for objects Constructed by a new Expression (Dynamic Storage-Duration) !
If none appropriate is found, the control flow continues to “Unwind”
Exceptions
CS-202 C. Papachristos
Exception(s) Implementation
The throw Expression
The throw Syntax:
/*a block scope somewhere*/
{
throw _expression_ ;
}
Or
/*a block scope somewhere*/
{
throw ;
}
Throwing can happen from inside a Function Block, a Class Method Block, an Unnamed Block, a try-catch Block, a Constructor, a Destructor (rarely), …
Exceptions
CS-202 C. Papachristos
Exception(s) Implementation
The throw Expression
The throw Syntax:
/*a block scope somewhere*/
{
throw _expression_ ;
}
Or
/*a block scope somewhere*/
{
throw ;
}
Evaluates the value of _expression_ and uses it to copy-initialize an Exception Object of the same type (Copy-ctor of the type must be available).
Abandons current catch Block and re-throws the currently handled Exception object (the exact same – not a copy).
Exceptions
CS-202 C. Papachristos
Exception(s) Implementation
The throw Expression
The throw Syntax:
/*a block scope somewhere*/
{
throw _expression_ ;
}
Or
/*a block scope somewhere*/
{
throw ;
}
Evaluates the value of _expression_ and uses it to copy-initialize an Exception Object of the same type (Copy-ctor of the type must be available).
Note:
“Stack Unwinding” after Exception Object Construction wipes away everything until it reaches a try Block. The only object that persists until reaching is the (temporary) Exception Object.
Abandons current catch Block and re-throws the currently handled Exception object (the exact same – not a copy).
Exceptions
CS-202 C. Papachristos
Exception(s) Implementation
The try – throw – catch Paradigm
Error – Handling By-Example:
void Car::setCarID(int id){
if (id < MIN_ID_VAL || id > MAX_ID_VAL)
cerr << "Requested ID is invalid, nothing changed…";
else
m_carID = id;
}
Exceptions
CS-202 C. Papachristos
Exception(s) Implementation
The try – throw – catch Paradigm
Error – Handling By-Example:
void Car::setCarID(int id){
if (id < MIN_ID_VAL || id > MAX_ID_VAL) {
throw (id) ;
}
m_carID = id;
}
…
Car myCar;
try{
myCar.setCarID(-1);
}
catch(const int & ex_id){
cerr << "Requested ID is invalid, nothing changed…";
}
Exceptions
CS-202 C. Papachristos
Exception(s) Implementation
The try – throw – catch Paradigm
Error – Handling By-Example:
void Car::setCarID(int id){
if (id < MIN_ID_VAL || id > MAX_ID_VAL) {
throw (id) ;
}
m_carID = id;
}
…
Car myCar;
try{
myCar.setCarID(-1);
}
catch(const int & ex_id){
cerr << "Requested ID is invalid, nothing changed…";
}
a) Erroneous case is detected, throw evaluates expression: (id) and derives a copy-initialized Exception Object of type int.
Exceptions
CS-202 C. Papachristos
Exception(s) Implementation
The try – throw – catch Paradigm
Error – Handling By-Example:
void Car::setCarID(int id){
if (id < MIN_ID_VAL || id > MAX_ID_VAL) {
throw (id) ;
}
m_carID = id;
}
…
Car myCar;
try{
myCar.setCarID(-1);
}
catch(const int & ex_id){
cerr << "Requested ID is invalid, nothing changed…";
}
b) Stack is Unwound until first try Block is encountered.
Exceptions
CS-202 C. Papachristos
Exception(s) Implementation
The try – throw – catch Paradigm
Error – Handling By-Example:
void Car::setCarID(int id){
if (id < MIN_ID_VAL || id > MAX_ID_VAL) {
throw (id) ;
}
m_carID = id;
}
…
Car myCar;
try{
myCar.setCarID(-1);
}
catch(const int & ex_id){
cerr << "Requested ID is invalid, nothing changed…";
}
c) Control is passed to matching-type catch Block.
Exceptions
CS-202 C. Papachristos
Exception(s) Implementation
The try – throw – catch Paradigm
Error – Handling By-Example:
void Car::setCarID(int id){
if (id < MIN_ID_VAL || id > MAX_ID_VAL) {
throw (id) ;
}
m_carID = id;
}
…
Car myCar;
try{
myCar.setCarID(-1);
}
catch(const int & ex_id){
cerr << "Requested ID is invalid, nothing changed…";
}
Note: Recommended practice is to�throw by-Value, catch by-Reference.
Exceptions
CS-202 C. Papachristos
Exception(s) Implementation
The try – throw – catch Paradigm
Stack Unwinding & Exception Object(s) By-Example:
void Car::setLicensePlates(const char * lPlates){
try{
std::string lPlates_str( lPlates );
if (lPlates_str.find_first_not_of("abcdef…ABCDEF…0123456789") {
throw (lPlates_str) ;
}
m_licensePlates = lPlates_str;
}
catch(const std::string & ex_lp){
cerr << "Plates " << ex_lp << " contain invalid characters…";
}
}
Exceptions
CS-202 C. Papachristos
Exception(s) Implementation
The try – throw – catch Paradigm
Stack Unwinding & Exception Object(s) By-Example:
void Car::setLicensePlates(const char * lPlates){
try{
std::string lPlates_str( lPlates );
if (lPlates_str.find_first_not_of("abcdef…ABCDEF…0123456789") {
throw (lPlates_str) ;
}
m_licensePlates = lPlates_str;
}
catch(const std::string & ex_lp){
cerr << "Plates " << ex_lp << " contain invalid characters…";
}
}
Stack Unwinding will first destroy lPlates_str before reaching the first try Block.
Exceptions
CS-202 C. Papachristos
Exception(s) Implementation
The try – throw – catch Paradigm
Stack Unwinding & Exception Object(s) By-Example:
void Car::setLicensePlates(const char * lPlates){
try{
std::string lPlates_str( lPlates );
if (lPlates_str.find_first_not_of("abcdef…ABCDEF…0123456789") {
throw (lPlates_str) ;
}
m_licensePlates = lPlates_str;
}
catch(const std::string & ex_lp){
cerr << "Plates " << ex_lp << " contain invalid characters…";
}
}
Stack Unwinding will first destroy lPlates_str before reaching the first try Block.
Exceptions
CS-202 C. Papachristos
Exception(s) Implementation
The try – throw – catch Paradigm
Stack Unwinding & Exception Object(s) By-Example:
void Car::setLicensePlates(const char * lPlates){
try{
std::string lPlates_str( lPlates );
if (lPlates_str.find_first_not_of("abcdef…ABCDEF…0123456789") {
throw (lPlates_str) ;
}
m_licensePlates = lPlates_str;
}
catch(const std::string & ex_lp){
cerr << "Plates " << ex_lp << " contain invalid characters…";
}
}
But the temporary Exception Object copy-initialized from expression lPlates_str is propagated in catch Block(s), and can be manipulated within them.
Exceptions
CS-202 C. Papachristos
Exception(s) Implementation
The try – throw – catch Paradigm
Combining with Flow Control By-Example:
int main(){
Car myCar;
while ( !myCar.IDisSet() ){
int id_input;
cin << id_input;
try{ myCar.setCarID(id_input); }
catch(const int & ex_id){
cerr << "Requested ID" << ex_id << "is invalid, retry…";
}
}
}
void Car::setCarID(int id){
if (id<MIN_ID_VAL || id>MAX_ID_VAL)
throw (id) ;
m_carID = id;
}
Exceptions
CS-202 C. Papachristos
Exception(s) Implementation
Exception–Handling Zero-Cost Model
“Simple” way:
bool Car::setCarID(int id){
if (id<MIN_ID_VAL || id>MAX_ID_VAL){
cerr << "Invalid ID…";
return false;
}
else
m_carID = id;
return true;
}
Car myCar;
if ( !myCar.setCarID(-1) ){
/*handle error in main program flow*/
}
Exceptions
CS-202 C. Papachristos
Exception(s) Implementation
Exception–Handling Zero-Cost Model
With Exceptions:
bool Car::setCarID(int id){
if (id<MIN_ID_VAL || id>MAX_ID_VAL){
cerr << "Invalid ID…";
return false;
}
else
m_carID = id;
return true;
}
Car myCar;
if ( !myCar.setCarID(-1) ){
/*handle error in main program flow*/
}
void Car::setCarID(int id){
if (id<MIN_ID_VAL || id>MAX_ID_VAL)
throw (id) ;
m_carID = id;
}
…
Car myCar;
try { myCar.setCarID(-1); }
catch (const int & ex_id) {
cerr << "Invalid ID…";
}
Exception-Handling code lies at a vtable outside of main program flow !
Exceptions
CS-202 C. Papachristos
Exception(s) Implementation
Catching (keyword catch) Semantics
The keyword catch requires:
_type_name_ (int, std::exception, std::out_of_range, …) and� _param_name_ (ex_id, ex, ex_oor, …, name is optional)
catch (const int & ex){ /*handling & manipulating ex*/ }
catch (const int &) { /*handling*/ }
Allows catching any type of Exception Object.
catch ( … ){ /*handling for any possible thrown exception*/ }
Or:
Exceptions
CS-202 C. Papachristos
Exception(s) Implementation
Catching (keyword catch) Semantics
To catch different Exception types, multiple catch Blocks are required:
try{
if ( !validIDInput(id) ){ throw (id); }
if ( !validLicencePlatesInput(lPlates_str) ){ throw (lPlates_str) }
}
catch( const int & ex_id){
cerr << "Input id" << ex_id << "is over/under the allowed limits…";
}
catch( const std::string & ex_plates){
cerr << "Input Plates " << ex_plates << "contain invalid characters…";
}
catch( … ){ cerr << "Unknown exception caught …"; }
…
…
…
Exceptions
CS-202 C. Papachristos
Exception(s) Implementation
Throwing (throw expression) Semantics
(Re-)throwing from inside a catch Block is allowed
try{
/* try top-level statements here … */
if ( !goodObjectCondition(myClassObject) ){ throw myClassObject; }
}
catch ( const myClassObject & ex_mc ){
try{
/* nested try (in catch) statements here … */
if ( logErrorCondition() ){ throw std::ios_base::failure(“( ͡° ͜ʖ ͡°)”); }
}
}
…
…
Example #1: Catches this,�but might also (re-)throw that.
Exceptions
CS-202 C. Papachristos
Exception(s) Implementation
Throwing (throw expression) Semantics
(Re-)throwing from inside a catch Block is allowed
try{
/* try top-level statements here … */
if ( !goodObjectCondition(myClassObject) ){ throw myClassObject; }
}
catch ( myClassObject & ex_mc ){
try{
/* nested try (in catch) statements here … */
ex_mc.setMemberValue(1.0);
if ( logErrorCondition() ){ throw ; }
}
}
Example #2: Catches this,�but might also (re-)throw it (the same Object).
…
Exceptions
CS-202 C. Papachristos
Exception(s) Implementation
Throwing (throw expression) Semantics
(Re-)throwing from inside a catch Block is allowed
try{
/* try top-level statements here … */
if ( !goodObjectCondition(myClassObject) ){ throw myClassObject; }
}
catch ( myClassObject & ex_mc ){
try{
/* nested try (in catch) statements here … */
ex_mc.setMemberValue(1.0);
if ( logErrorCondition() ){ throw ; }
}
}
Example #2: Catches this,�but might also (re-)throw it (the same Object).
Note: Exception Object in this Handler is non-const → can modify it.
…
Exceptions
CS-202 C. Papachristos
Exception(s) Implementation
Throwing (throw expression) Semantics
throwing from inside a catch Block is allowed
try{
/* try top-level statements here … */
if ( !goodObjectCondition(myClassObject) ){ throw myClassObject; }
}
catch ( myClassObject& ex_mc ){
try{
/* nested try (in catch) statements here … */
ex_mc.setMemberValue(1.0);
if ( logErrorCondition() ){ throw ; }
}
}
Example #2: Catches this,�but might also (re-)throw it (the same Object).
Note: Do not use throw ex_mc; → Will copy-initialize Exception� Object again and delete –call Destructor of– original (+Slicing Possibility).
…
Exceptions
CS-202 C. Papachristos
Exception(s) Implementation
Throwing (throw expression) Semantics
throwing and not catching results in Uncaught Exception(s)
Uncaught / Unhandled Exceptions will cause the std::terminate() function to be called.
Exceptions
CS-202 C. Papachristos
Exception(s) Implementation
Throwing (throw expression) Semantics
throwing from Functions
Requirements – prior to C++11 Standard:
Exceptions
CS-202 C. Papachristos
Exception(s) Implementation
Throwing (throw expression) Semantics
Function throw Lists – prior to C++11 Standard:
(it will not catch and handle it internally, and it will propagate).
throw Lists should match up with what is thrown and not caught inside the function. Otherwise, the function std::unexpected() is called:
Exceptions
CS-202 C. Papachristos
Exception(s) Implementation
Throwing (throw expression) Semantics
Function throw Lists – prior to C++11 Standard:
// Throws only 1 type of exception
_ret_type_ myFunc1( _params_list_ ) throw (_ex_type_);
// Throws 2 types of exceptions (comma separated list)
_ret_type_ myFunc2( _params_list_ ) throw (_ex_type_1_, _ex_type_2_);
// Promises not to throw any exceptions
_ret_type_ myFunc0(_params_list_ ) throw ( );
// Can throw any exceptions
_ret_type_ myFunc(_params_list_ );
Can be of type
int, std::string,�std::exception,�std::bad_alloc, std::ios_base_failure, …
Exceptions
CS-202 C. Papachristos
Exception(s) Implementation
Function throw Lists – prior to C++11 Standard:
By-Example:
void Car::setCarID(int id) throw(int) {
if (id < MIN_ID_VAL || id > MAX_ID_VAL) { throw (id) ; }
m_carID = id;
}
int main(){
Car myCar;
try{ myCar.setCarID(-1); }
catch(const int & ex_id){
cerr << "Requested ID" << ex_id << "is invalid, nothing changed…";
}
}
Dynamic Exception Specification notifies that the Function might throw an int at run time.
Function is called with bad argument and throws.
Exception handled outside of throwing Function.
Exceptions
CS-202 C. Papachristos
Exception(s) Implementation
Throwing (throw expression) Semantics
Post C++11 Standard – Function throw Lists are deprecated
Why?
Exceptions
CS-202 C. Papachristos
Exception(s) Implementation
Throwing (throw expression) Semantics
Post C++11 Standard – Function throw Lists are deprecated
In practice two forms of Exception-Throwing guarantees are useful:
_ret_type_ myFunc(_params_list_ );
_ret_type_ myFunc(_params_list_ ) noexcept ;
Simply omit Exception Specification.
noexcept Specifier introduced in C++11: Unlike empty throw(), it does not require the compiler to introduce code to check whether an exception is thrown (If a noexcept Function is exited via Exception, std::terminate() is called).
Exceptions
CS-202 C. Papachristos
Exception(s) Implementation
Exception–Handling and Nested Functions:
By-Example:
int main(){
try{
func_level_1();
}
catch(const int & ex){
cerr << ex;
}
}
class AClass{
public:
AClass()
{ cout << "A ctor"; }
~AClass()
{ cout << "A dtor"; }
};
class BClass{
public:
BClass()
{ cout << "B ctor"; }
~BClass()
{ cout << "B dtor"; }
};
void func_level_1() {
AClass aC;
func_level_2();
}
void func_level_2() {
BClass bc;
throw (-1);
}
Exceptions
CS-202 C. Papachristos
Exception(s) Implementation
Exception–Handling and Nested Functions:
By-Example:
int main(){
try{
func_level_1();
}
catch(const int & ex){
cerr << ex;
}
}
void func_level_1() {
AClass aC;
func_level_2();
}
void func_level_2() {
BClass bc;
throw (-1);
}
class AClass{
public:
AClass()
{ cout << "A ctor"; }
~AClass()
{ cout << "A dtor"; }
};
class BClass{
public:
BClass()
{ cout << "B ctor"; }
~BClass()
{ cout << "B dtor"; }
};
A ctor → B ctor
Output:
Exceptions
CS-202 C. Papachristos
Exception(s) Implementation
Exception–Handling and Nested Functions:
By-Example:
int main(){
try{
func_level_1();
}
catch(const int & ex){
cerr << ex;
}
}
void func_level_1() {
AClass aC;
func_level_2();
}
void func_level_2() {
BClass bc;
throw (-1);
}
Stack Unwinding process
A ctor → B ctor → B dtor → A dtor
Output:
class AClass{
public:
AClass()
{ cout << "A ctor"; }
~AClass()
{ cout << "A dtor"; }
};
class BClass{
public:
BClass()
{ cout << "B ctor"; }
~BClass()
{ cout << "B dtor"; }
};
Exceptions
CS-202 C. Papachristos
Exception(s) Implementation
Exception–Handling and Nested Functions:
By-Example:
int main(){
try{
func_level_1();
}
catch(const int & ex){
cerr << ex;
}
}
void func_level_1() {
AClass aC;
func_level_2();
}
void func_level_2() {
BClass bc;
throw (-1);
}
A ctor → B ctor → B dtor → A dtor → -1
Output:
class AClass{
public:
AClass()
{ cout << "A ctor"; }
~AClass()
{ cout << "A dtor"; }
};
class BClass{
public:
BClass()
{ cout << "B ctor"; }
~BClass()
{ cout << "B dtor"; }
};
Exceptions
CS-202 C. Papachristos
Exception(s) Implementation
Exception Class(es)
The try – throw – catch Paradigm works with Exception Objects
(std::exception, std::runtime_error, std::ios_base::failure are Classes)
Exception Class Hierarchies using Inheritance can also be created.
Exceptions
CS-202 C. Papachristos
Exception(s) Implementation
Exception Class(es)
General Approach:
a) a parameter value, b) the name of Function that detected the error, c) an error description
Exception Class is required to have:
a) Constructor(s) – and Copy-Constructor available (can be the default).
b) Accessor(s) – for member access.
Exceptions
CS-202 C. Papachristos
Exception(s) Implementation
Exception Class(es) – By-Example:
class MathExcept {
public:
MathExcept(int code,
string description){
m_code=code;
m_description=description;
}
MathExcept(const MathExcept & o){
m_code=o.m_code;
m_description=o.m_description;
}
int GetCode() const
{ return m_code; }
string GetDescription() const
{ return m_description; }
private:
int m_code;
string m_description;
};
class DivByZeroExcept : public MathExcept {
public:
DivByZeroExcept(double numerator,
int code, string description)
: MathExcept(code, description){
m_numerator = numerator;
}
DivByZeroExcept(const DivByZeroExcept & o)
: MathExcept(o){
m_numerator=o.m_numerator;
}
double GetNumerator() const
{ return m_numerator; }
private:
double m_numerator;
};
Exceptions
CS-202 C. Papachristos
Exception(s) Implementation
Exception Class(es) – By-Example:
class MathExcept {
public:
MathExcept(int code,
string description){ … }
MathExcept(const MathExcept & o){ … } …
};
class DivByZeroExcept : public MathExcept {
public:
DivByZeroExcept(double numerator,
int code, string description)
: MathExcept(code, description){
m_numerator = numerator;
}
DivByZeroExcept(const DivByZeroExcept & o)
: MathExcept(o){
m_numerator=o.m_numerator;
}
double GetNumerator() const
{ return m_numerator; }
private:
double m_numerator;
};
Note:
The only way to call Base Class ctor from Derived Class ctor is via Initialization List(s).
Exceptions
CS-202 C. Papachristos
Exception(s) Implementation
Exception Class(es) – By-Example:
try{
…
}
catch(const DivByZeroExcept & ed){
…
}
try{
…
}
catch(const MathExcept & em){
…
}
class DivByZeroExcept : public MathExcept {
public:
DivByZeroExcept(double numerator,
int code, string description)
: MathExcept(code, description){ … }
DivByZeroExcept(const DivByZeroExcept & o)
: MathExcept(o){ … }
…
};
class MathExcept {
public:
MathExcept(int code,
string description){ … }
MathExcept(const MathExcept & o){ … } …
};
Exceptions
CS-202 C. Papachristos
Exception(s) Implementation
Exception(s) in Class ctor(s)
Good idea to perform Handling of Failed Constructor(s):
Note:
The Destructor of the Class that throws the Exception is not automatically called (only Stack Unwinding is performed).
Exceptions
CS-202 C. Papachristos
Exception(s) Implementation
Exception(s) in Class ctor(s)
Good idea to perform Handling of Failed Constructor(s):
MyClass::MyClass ( int val ) {
…
/* detection of failure*/
if ( bad_state_detected() )
throw ConstructorFailure( );
…
}
int main(){
MyClass * mc_Pt;
try{
mc_Pt = new MyClass(1000);
}
catch(const ConstructorFailure & e){
mc_Pt = nullptr;
}
}
Class Deallocation function is handled when Exception leaves the new-Expression Constructor, while internally created sub-Objects are deleted via Stack Unwinding.
Exceptions
CS-202 C. Papachristos
Exception(s) Implementation
Exception(s) in Class dtor(s)
Bad idea to perform Handling of Failed Destructor(s):
Time for Questions !
CS-202
CS-202 C. Papachristos