Not logged in, Join Here! or Log In Below:  
 
News Articles Search    
 

 Home / General Programming / Exceptions with templates Account Manager
 
Archive Notice: This thread is old and no longer active. It is here for reference purposes. This thread was created on an older version of the flipcode forums, before the site closed in 2005. Please keep that in mind as you view this thread, as many of the topics and opinions may be outdated.
 
Markowitch

April 03, 2005, 10:56 AM

Hi flipcoders

At work we have an application with an error logging system that reguires information about which file and line the error occured in. This is accomplished by using the __FILE__ and __LINE__ macros.

I want to combine this system with an exception hierarchy (std::exception) and I think I have found a solution involving templates. But since I have never seen examples that mix templates and exceptions I would like to get some feedback from all the experts here :-)

The template exception acts as a wrapper, which eliminates a lot of specialized subclasses. Anyway I'm not so familiar with c++ exception coding style. Is it normal just to use std::exception and nothing else? Or is it more common to use specialized exceptions e.g. like std::runtime_error in a production environment?

I've provided three catch clauses to illustrate the flexibility of the template exception, each of which would be able to catch the error.

/Markowitch

  1.  
  2. #include "stdafx.h"
  3. #include <iostream>
  4. #include <exception>
  5.  
  6.  
  7. using namespace std;
  8.  
  9. typedef const char* exString;
  10.  
  11. // -----------------------------------------------
  12.  
  13. class consoleExceptionInterface
  14. {
  15. public:
  16.        
  17.         virtual exString GetFile() = 0;
  18.  
  19.         virtual int GetLine() = 0;
  20.  
  21.         virtual exString GetMessage() = 0;
  22. };
  23.  
  24. // -----------------------------------------------
  25.  
  26. template<class T>
  27. class exceptionWrapper : virtual public T, virtual public consoleExceptionInterface
  28. {
  29. private:       
  30.         exString file_;
  31.         int line_;     
  32.  
  33. public:
  34.         exceptionWrapper(exString message, exString file, int line)
  35.                 : T(message), file_(file), line_(line)
  36.         {
  37.                
  38.                 // compile time check to ensure template is derived from exception
  39.                 T instance("");
  40.                 exception e = static_cast<exception>(instance);        
  41.         }
  42.        
  43.         virtual ~exceptionWrapper() {}
  44.  
  45.         exString GetFile() { return file_; }
  46.  
  47.         int GetLine() { return line_; }
  48.        
  49.         virtual exString GetMessage()
  50.         {
  51.                 return what();
  52.         }
  53. };
  54.  
  55. // -----------------------------------------------
  56.  
  57. class Test
  58. {
  59.  
  60. public:
  61.        
  62.         void throwException()
  63.         {
  64.                 exceptionWrapper<runtime_error> error("An unknown runtime error", __FILE__, __LINE__); 
  65.                 throw error;
  66.         }      
  67. };
  68.  
  69. // -----------------------------------------------
  70.  
  71. int main(int argc, char* argv[])
  72. {
  73.         cout << "Exception test" << endl;
  74.        
  75.         try
  76.         {              
  77.                 Test test;
  78.                 test.throwException();
  79.         }
  80.         catch(exceptionWrapper<runtime_error>& e)
  81.         {
  82.                 cout << "-----------------------" << endl;
  83.                 cout << e.GetMessage() << endl;
  84.                 cout << e.GetFile() << "(" << e.GetLine() << ")" << endl;
  85.  
  86.         }
  87.         catch(consoleExceptionInterface& e)
  88.         {              
  89.                
  90.                 cout << e.GetMessage() << endl;
  91.                 cout << e.GetFile() << "(" << e.GetLine() << ")" << endl;
  92.         }
  93.         catch(exception& e)
  94.         {
  95.                 cout << e.what() << endl;
  96.         }
  97.        
  98.         cin.get();
  99.         return 0;
  100. }
  101.  



 
Markowitch

April 03, 2005, 11:02 AM

Hmm - I forgot the public virtual destructor in the interface

 
Patrick Grawehr

April 03, 2005, 02:58 PM

Nope, you did not. Interfaces do not need destructors (neither virtual ones nor non-virtual ones), because they don't contain any data that should be free'd.
Personally, I would avoid defining templates that inherit from their template parameter type, because it's very hard to read and to actually understand what kind of operations the resulting class has. And for exceptions in particular, I would go with the "normal" way of inheritance, because the hierarchy is very important here and should be easily recognizable when reading the code.

 
Markowitch

April 04, 2005, 04:20 AM

Patrick Grawehr wrote: For exceptions in particular, I would go with the "normal" way of inheritance, because the hierarchy is very important here and should be easily recognizable when reading the code. [/i]


My plan is to use this templated exception class to precisely mimimc the std::exception hierarchy. Hence the compile time check to ensure that T is a derivative of std::exception.

As I see it, this is an advantage. If you know the std::exception hierarchy then you will also know the exceptionWrapper hierarchy.

But what about the other question I posted: What is the prefered coding style regarding exceptions - do you exploit the hierarchy or do you just use std::exception ??

Regards
/Markowitch

 
Chad Austin

April 04, 2005, 05:07 AM

Interesting bit of code.

I usually make my own base Exception class (derived from std::exception of course) and then subclass that for my purposes. (catching pyr::FileOpenError when needed, etc.)

In really simple projects, throwing std::runtime_error seems to work okay.

Keep us updated on how well your setup works for you...

 
This thread contains 5 messages.
 
 
Hosting by Solid Eight Studios, maker of PhotoTangler Collage Maker.