Re: ExceptionHandler class & list of error messages ?
mast2as@yahoo.com wrote:
Hi everyone... I have a TExceptionHandler class that is uses in the
code to thow exceptions. Whenever an exception is thrown the
TExceptionHander constructor takes an error code (int) as an argument.
I was hoping to create a map<int, const char*> that would be used in
the showError member function of the TExceptionHandler class where the
key (int) would be the error code and const char* the message printed
out to the console.
My question is the following. What would be the best way of creating
that map ? Here is why I am asking. I believe when you throw an
exception you actually create a copy of the object TExceptionHandler.
So if the map is a member variable of the class and that each entry in
the map is intialised with a string (as an error message) it would be a
waste of CPU time & memory (just stupide to create that list eveytime a
TExceptionHandler object is created).
Is the best way, to make the TExceptionHandler class a singleton ? The
map could a static member variable and would be intialised only once.
Or should I make the map a global variable (like an array of const
char* or string) and just use that global variable in the showError()
function ?
I am sure there's a good way of doing that ;-)
I looked on the net and the groups' archives but couldn't find anything
related on that precise aspect of exception handling.
Why not make it a private static member in your class:
class TException
: std::exception
{
public:
enum ErrorCode
{
SOMETHING_HAPPENED = 1,
SOMETHING_ELSE = 5,
SOMETHING_STRANGE = 42
};
typedef std::map<ErrorCode, const char*> MsgMap;
// Only one constructor is needed
TException(
const ErrorCode code,
const int severity = GIE_ERRORPRINT )
: m_code( error )
, m_severity( severity )
{}
virtual const char* what() const
{
return msgMap_[ code_ ];
}
int severity() const
{
return severity_;
}
private:
const static MsgMap msgMap_;
const ErrorCode code_;
const int severity_;
};
Then in the .cpp file, use an initializer helper class to initialize
it:
namespace // anonymous
{
class MsgMapInitializer
{
TException::MsgMap m_;
public:
operator TException::MsgMap() const { return m_; }
MsgMapInitializer& Add( const int i, const char* s )
{
m_[i] = s;
return *this;
}
};
}
const TException::MsgMap TException::msgMap_ = MsgMapInitializer()
.Add( TException::SOMETHING_HAPPENED, "Msg 1" )
.Add( TException::SOMETHING_ELSE, "Msg 2" )
.Add( TException::SOMETHING_STRANGE, "Msg 3" );
Then you can use it like this:
try
{
throw TException( TException::SOMETHING_ELSE, 100 );
}
catch( const std::exception& e )
{
std::cerr << e.what() << std::endl; // Or whatever
}
[snip]
void showError()
{
// print out the error message base of the error code
cout << globalErrorMessageList[ m_error ] << endl; << is that the
best option ?
}
Typically it is best to inherit from std::exception and override the
virtual function what() to return an error message. Then the user can
do whatever s/he wants with it rather than being forced to use cout
(which is often impractical in GUI and embedded applications).
private:
int m_code;
int m_severity;
const char* m_message;
};
Why store the message locally? Just look it up when its time to use it
(probably only once).
Cheers! --M