1. Trang chủ
  2. » Công Nghệ Thông Tin

A Complete Guide to Programming in C++ part 65 pot

10 209 0
Tài liệu đã được kiểm tra trùng lặp

Đang tải... (xem toàn văn)

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Tiêu đề Defining Your Own Error Classes
Thể loại Bài luận
Định dạng
Số trang 10
Dung lượng 184,14 KB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

䊐 Exception Class MembersWhen an exception is thrown, the exception object type determines which exception handler will be executed.. When an exception is thrown, Example: throw MathErro

Trang 1

䊐 Exception Class Members

When an exception is thrown, the exception object type determines which exception handler will be executed For this reason, an exception class does not need to have any members

However, an exception class can contain data members and methods—just like any other class This makes sense, as locally defined non-static objects are destroyed when an exception has been thrown and the stack is unwound Thus, the exception handler can

no longer access the previously existing objects

You can use the data members of error classes to rescue data threatened by an error condition For example, you can store data important for exception handling in an exception object

The exception class MathErroris defined opposite The calc()function throws an exception when a number input by a user is negative or 0 When an exception is thrown,

Example: throw MathError("Division by 0!");

the error message is stored in the exception object The exception handler can then use thegetMessage()method to evaluate the message

䊐 Exception Hierarchies

New exception classes can be derived from existing exception classes A base class will normally represent a general error type and specific errors will be represented by derived classes

Thus, the exception class MathErrorcould be defined to represent general errors in mathematical computations, but it would make sense to define derived exception classes for special cases, such as “Division by 0” or “Arithmetic overflow.” You could call these classesDivisionByZeroandOverflowError, for example

Be aware of the following rules for exception handlers in this context:

■ given that T is a derived exception class, special errors of this type are handled by the exception handler

■ if T is a base class, the handler will also catch the exception objects thrown by derived classes, thus providing similar handling for generic and specific errors

Trang 2

620 C H A P T E R 2 8 E X C E P T I O N H A N D L I N G

invalid_argument out_of_range

length_error domain_error

Invalid argument Argument value not in its expected range Length exceeds maximum capacity Domain error reported by the implementation

range_error

underflow_error overflow_error

Range error in internal computation Arithmetic underflow error

Arithmetic overflow error

// Subscript operator of class FloatArr throws // exceptions with type of standard class out_of_range: //

-#include <stdexcept>

#include <iostream>

using namespace std;

double& FloatArr::operator[](int i) throw(out_of_range)

{ if( i < 0 || i >= anz )

throw out_of_range("Invalid index!");

else return arrPtr[i];

} // - Test Program -int main()

{

try {

// Uses arrays of type FloatArr

} catch(out_of_range& err) {

cerr << err.what() << endl;

}

// The program continues here

}

Exception classes derived from logic_error

Exception classes derived from runtime_error

Using standard exception classes

Trang 3

䊐 Hierarchy of Standard Exception Classes

The C++ standard library contains various exception classes, which are used in the string and container libraries, for example However, the standard exception classes can be used just like exception classes of your own Their definitions are to be found in the header file stdexcept

The standard exception classes are organized in a hierarchy, the common base class being the exceptionclass In addition to a default constructor, a copy constructor, and

an assignment, this class contains a virtual public method,what(), which returns a message on the error cause as a C string

䊐 Representing Logic Errors and Runtime Errors

The following exception classes are derived from the exceptionclass:

logic_error used to represent logic errors, caused by anomalies in the program’s

logic These errors can be avoided

runtime_error used to represent runtime errors, such as under- or overflows

occur-ring in internal computations These errors are unpredictable The opposite page contains on overview of the exception classes derived from the

logic_error andruntime_error classes For example, the method at() in the

stringclass throws an out_of_rangetype exception when an invalid string position

is passed to it If a string cannot be displayed because of its exceptional length, an excep-tion of the invalid_argumenttype is thrown

An exception of the overflow_errororunderflow_errortype is thrown if the value to be displayed is too large or too small for the type in use The range_error

class shows range errors, which can occur during internal computations

A constructor with a string as a parameter is defined in every class derived from

exception This means you can initialize exceptions of these types with error messages Thewhat()method returns this error message as a C string

Trang 4

622 C H A P T E R 2 8 E X C E P T I O N H A N D L I N G

Error in reading:

Invalid index:

Error in writing:

Invalid index:

Exercise 1: Error messages of the exception handler

The first exception handler’s message:

The second exception handler’s message:

Trang 5

Exercise 1

TheFloatArrclass needs exception handling for cases where an invalid index is stated when accessing an array member.

■ Define the exception class BadIndexfor this purpose and store the class

in the header file “floatArr.h”.The exception class must contain a data member to store the invalid index.The constructor expects an index that it will copy to the data member.The constaccess method

getBadIndex()returns the data member.

Both subscript operators should be able to throw BadIndextype excep-tions.Add an exception specification to the declaration of the subscript operators.

The methods that expect the position as an argument, such as insert()

andremove(), should also throw exceptions.Add appropriate exception specifications to the definitions and change the return types from boolto

void.

■ Change the definitions of the methods and operator functions to allow a

BadIndextype exception to be thrown when the index passed to the function is outside the valid range.

■ Write a mainfunction where a constant vector is created and initialized with fixed values Exception handling is required for the following scenar-ios.The array elements are displayed and an index is read until an invalid index value is input.The catchhandler should output the information shown opposite for each invalid index.

Then create a non-constant array.Add further exception handling to be performed Elements are appended or inserted within a tryblock.

Include an invalid element access attempt, which causes the catch han-dler to output the information shown opposite.Then finally output the array elements outside the tryandcatchblocks.

Trang 6

624 C H A P T E R 2 8 E X C E P T I O N H A N D L I N G

Exercises

For Exercise 2: Error messages of the exception handlers

Messages of the exception handlers for an exception object of type DivisionByZero:

Error in initializing:

The denominator is 0!

Error in division:

No division by zero!

Error: Denominator is 0!

New denominator != 0:

Trang 7

Exercise 2

Implement exception handling for the Fractionclass, which is used to

represent fractions (see Exercise 2, Chapter 19) Dividing by 0 throws an

exception that affects the constructor for the Fractionclass and the operator functions/and>>.

■ Define the exception class DivError, which has no data members, within theFractionclass.The exception class is of the following type

Fraction::DivError

Add an appropriate exception specification to the declarations of the constructor and the operator functions /and>>.

■ Change the definition of the constructor in the Fractionclass If the value of the denominator is 0, a DivisionByZerotype exception should

be thrown.

■ Similarly modify the operator functions.

■ Now write a mainfunction to test the various exceptions.You will need

to arrange three different tryandcatchblocks sequentially.

The first try/catchblock tests the constructor Create several fractions, including some with a numerator value of 0 and one with 0 as its

denominator.The exception handler should issue the error message shown opposite.

The second try/catchblock tests divisions Use a statement to attempt

to divide by 0.The corresponding exception handler should send the second error message shown opposite to your standard output.

The third try/catchblock reads numerators and denominators of fractions in dialog If the value of the denominator is 0, the denominator is read again If the value is still 0, the third error message as shown

opposite is output and the program terminates.

Trang 8

626 C H A P T E R 2 8 E X C E P T I O N H A N D L I N G

Exercise 1

// -// floatArr.h : Represents dynamic float arrays

// Methods throw exceptions for an invalid index

//

-#ifndef _FLOATARR_

#define _FLOATARR_

#include <iostream>

using namespace std;

class BadIndex

{ private:

int index;

public:

BadIndex(int i){index = i;}

int getBadIndex() const {return index;}

};

class FloatArr

{ private:

float* arrPtr; // Dynamic member int max; // Maximum number without

// reallocating more memory

int cnt; // Current number of elements

void expand( int newSize); // Function to help

// enlarge the array public:

FloatArr( int n = 256 ); // Constructors FloatArr( int n, float val);

FloatArr(const FloatArr& src);

~FloatArr(); // Destructor FloatArr& operator=( const FloatArr&); // Assignment

int length() const { return cnt; }

// Subscript operators:

float& operator[](int i) throw(BadIndex);

float operator[](int i) const throw(BadIndex);

// Methods to append a float value // or an array of floats:

void append( float val);

void append( const FloatArr& v);

Trang 9

FloatArr& operator+=( float val)

{

append( val); return *this;

}

FloatArr& operator+=( const FloatArr& v)

{

append(v); return *this;

}

// Methods to insert a float value

// or an array of float values:

void insert( float val, int pos) throw(BadIndex);

void insert(const FloatArr& v,int pos) throw(BadIndex); void remove(int pos) throw(BadIndex); // Remove

// at pos

// Output the array

friend ostream& operator<<( ostream& os,

const FloatArr& v) {

int w = os.width(); // Save field width

for( float *p = v.arrPtr; p < v.arrPtr + v.cnt; ++p) {

os.width(w); os << *p;

}

return os;

}

};

#endif // _FLOATARR_

//

-// floatArr.cpp

// Implementing the methods of FloatArr

//

-#include "floatArr.h"

// Constructors

-FloatArr::FloatArr( int n )

{

max = n; cnt = 0; // Sets max and cnt

arrPtr = new float[max]; // Allocates memory

}

FloatArr::FloatArr(int n, float val)

{

max = cnt = n;

arrPtr = new float[max];

for( int i=0; i < cnt; ++i)

arrPtr[i] = val;

}

Trang 10

628 C H A P T E R 2 8 E X C E P T I O N H A N D L I N G

FloatArr::FloatArr(const FloatArr& src) {

max = src.max;

cnt = src.cnt;

arrPtr = new float[max];

for( int i = 0; i < cnt; i++ ) arrPtr[i] = src.arrPtr[i];

}

// Destructor -FloatArr::~FloatArr() {

delete[] arrPtr;

}

// Private functions to help enlarge the array

void FloatArr::expand( int newSize) {

if( newSize == max) return;

max = newSize;

if( newSize < cnt) cnt = newSize;

float *temp = new float[newSize];

for( int i = 0; i < cnt; ++i) temp[i] = arrPtr[i];

delete[] arrPtr;

arrPtr = temp;

}

FloatArr& FloatArr::operator=( const FloatArr& src ) {

if( this != &src ) // No self assignment! {

max = src.max;

cnt = src.cnt;

delete[] arrPtr; // Release memory,

arrPtr = new float[max]; // reallocate,

for( int i=0; i < cnt; i++) // copy elements arrPtr[i] = src.arrPtr[i];

} return *this;

}

Ngày đăng: 06/07/2014, 17:21

TỪ KHÓA LIÊN QUAN