473,545 Members | 1,310 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

deriving from std::exception and overiding what() to construct dynamic messages.

8 New Member
Hello Guys and Galls,

To start off, I have reached the solution I was looking for, but I would like comments and feedback on the solution I have reached and tips/tricks on making it more elegant. I am not satisfied with the underlying machinery of the solution though.

I am an advanced C programmer and most do object-based programming in C++. Please do not reply to this article with references to basic material or obvious tips.

An overview to the problem I was trying to solve ; I have written a very complex plugin for a webserver and it shows some bugs only with live use (to be specific a ISAPI Filter for Microsoft IIS). I was not given the go ahead to do live debugging on the server and it might not have helped track the bug anyway. In order to catch it I have to improve the instrumentation of my software.

The error codes in the server (win32 API numeric error codes) are mostly converted into exceptions but the exceptions weren't intelligent in any way... they were all stand-alone and did not derive from a standard heirarchy. I need a standard heirarchy to maintain sanity and I need the debug messages to be dynamic. std::exception as a base class was the obvious choice (wish I hadn't gone down that route now :D ) .

I want the exceptions to have a title and a body and I would obviously want to generate the body at runtime.The problem is that the what() method signature from std::exception defines the what as a const method.

Getting arround the const restriction leads to a ton of fidley code, which I should say I cannot accept it has made me hate aspects of the C++ language and the std library, I certainly would have faired better implementing the following in straight C, however saying this I want my faith restored in the language and shown why I am being unfair. The following solution has taken me about 10 hours of refactoring.

The custom exception for my project requires the following semantics.

Expand|Select|Wrap|Line Numbers
  1. class CustomException
  2.     : public SStreamException
  3. {
  4. public :
  5.     CustomException(char * file_in,DWORD line_in)
  6.         : SStreamException(file_in,line_in) {}
  7.     virtual const char * getType() const
  8.     {
  9.         return "testing";
  10.     }
  11.     virtual void getBody(std::stringstream & body_in) const
  12.     {
  13.         body_in << "My Sexy Body";
  14.     }
  15. };
so the two methods getType() and getBody() are called from the what() method in SStreamExceptio n(which extends std::exception) resulting in a runtime dynamic error message. I guess this uses the delegate pattern. I am satisfied with these semantics and it should make my exception definitions look clean and elegant.

The Following is the underlying machinery to support the dynamic what() method.

Expand|Select|Wrap|Line Numbers
  1. #include <sstream>
  2. #include <string>
  3. #include <windows.h>
  4.  
  5. /* Uses std::string to maintain the string. string::c_str() is a (const char *). 
  6.  * if std::stringstream::str()::c_str() is used the intermediary string object
  7.  * vanishes at end of scope (return). Note that it derives from strinstream 
  8.  */
  9. class DynamicConstString
  10.     : public std::stringstream
  11. {
  12. private : 
  13.     std::string * _privateConstString;
  14. public:
  15.     DynamicConstString()
  16.         : _privateConstString(NULL)
  17.     {
  18.         _privateConstString=new std::string();
  19.     }
  20.     ~DynamicConstString()
  21.     {
  22.         if(_privateConstString!=NULL)
  23.             delete _privateConstString;
  24.     }
  25.  
  26.     /* prior to a clear the string is constant */
  27.     const char * getCString()
  28.     {
  29.         _privateConstString->assign((*this).str());
  30.         return _privateConstString->c_str();
  31.     }
  32.  
  33.     /* empty the string state in preparation of new data */
  34.     void recycle()
  35.     {
  36.         _privateConstString->assign("");
  37.         (*this).str(*_privateConstString);
  38.     }
  39. };
  40.  
  41.  
  42. class SStreamException
  43.     : public std::exception
  44. {
  45.     char * file;
  46.     DWORD line;
  47.     /* For some reason (cannot remember)  the following two objects need to be 
  48.      * heap allocated for const correctness */
  49.     DynamicConstString * __debugMsgString;
  50.     DynamicConstString * __bodyString;
  51.  
  52. public:
  53.     /* Following methods need to be defined by the Children */
  54.     virtual const char * getType() const
  55.     {
  56.         return "Type Unspecified";
  57.     }
  58.     virtual void getBody(std::stringstream & _bodyString_in) const
  59.     {
  60.            _bodyString_in << "";
  61.     }
  62.  
  63.     SStreamException(char * file_in, DWORD line_in)
  64.         : file(file_in), line(line_in),__debugMsgString(NULL),__bodyString(NULL)
  65.     {
  66.         __debugMsgString=new DynamicConstString();
  67.         __bodyString=new DynamicConstString();
  68.     }
  69.     ~SStreamException()
  70.     {
  71.         if(__debugMsgString!=NULL)
  72.             delete __debugMsgString;
  73.         if(__debugMsgString!=NULL)
  74.             delete __bodyString;
  75.     }
  76.  
  77.  
  78.  
  79.     const char * what() const throw()
  80.     {
  81.  
  82.         __debugMsgString->recycle();
  83.         __bodyString->recycle();
  84.  
  85.         std::stringstream & debugMsgString=*__debugMsgString;
  86.         std::stringstream & bodyString=*__bodyString;
  87.  
  88.         debugMsgString << "Exception : " << getType() << std::endl;
  89.         debugMsgString << "(" << file << ":" << line << ")" << std::endl;
  90.  
  91.         getBody(bodyString);
  92.  
  93.         /* if (bodyString.str()) is not used the pointer of (__bodystring) is used 
  94.          * for some reason. weird reason */
  95.         debugMsgString << (bodyString.str());
  96.  
  97.         return __debugMsgString->getCString();        
  98.     }
  99. };
  100.  
To end I guess the core things I want to know are,

(1) Why the hell is what() marked as a const function ? is this braindead
or is there a justification for this.

(2) Have I circumvented the const correctness of std::exception: :what()

(3) is their a more elegant way to do this.

(4) are there more specialized libraries that do what I am trying to do for c++. (perhaps in boost ? Or Such).

(5) Could someone point me to some advanced articles on const correctness and the pitfalls of C++ object orientation.

(6) Is C++0x or the TR1 of boost attempting to make expressing such semantics in C++ better ? (perhaps the new garbage collector) And if so How ?

Looking forward to your feedback

Regards

Vain
Apr 10 '09 #1
3 6420
weaknessforcats
9,208 Recognized Expert Moderator Expert
The STL exception::what () is a const member function so you can use with const objects.

It returns a const char* so you can't alter the string pointed at since that may itself be a const string.

Personally, when I use this thing, my override a) dumps all my data to a log file, b) obtains the userid, machine name, IP address, system date an time, etc... and dumps all that to the log file.

Then I return "It bombed!".

exception::what () was never intended to be used just by looking at the returned char*.

Since you are an advanced C++ developer, you know that a cast of any kind means a) you are calling a relic C function, or b) your C++ design is screwed up.

That said, you never alter const. The only safe alteration of const is to const_cast a const object to a non_const object so you can call a non-const function with a const object. Going the other way, a const_cast is only safe when you know the non-const object was const to begin with. All other const casts are hacks and elicit undefined behavior by your compiler.

This is basic Stroustrup and it's in his book.

The one weakness of the STL is that is persists in using public virtual functions which are a big no-no since they merge the implementation (the virtual function) with the interface (the public methods). Scott Meyers has material on this or you could just look at the Template design pattern.
Apr 10 '09 #2
vainstah
8 New Member
const_cast had completely slipped my mind. If I had marked the objects I am using for string manipulation as const (I think) I would not have had to add an extra level of indirection to my code, I would have done a const_cast.

Your tip has directly addressed my confusion. Thank you.

I am still a bit miffed at how the const keyword is used in C++. I appreciate the need for it in the design of an API and as a tool to reduce complexity. I guess by specifying the virtual function as const the library writer can say "Hey MR. DeriveFromMyObj ect,, I don't want to be responsible for altering the state of your object, so I will ask Mr. Compiler to police you".

Now that I understand the problem and its solution I am wondering if perhaps in this scenario the prevention of misuse should better be left to the programmer ? It lowers the barrier to entry for C++ programming. In my opinion the real skill lies in understanding the low-level programming and not in the knowledge of a complex language.
Apr 14 '09 #3
weaknessforcats
9,208 Recognized Expert Moderator Expert
In my opinion the real skill lies in understanding the low-level programming and not in the knowledge of a complex language.
True for C but not true for C++.

C++ precisely wants you to avoid that low-level stuff. That's why there is an STL that uses algorithms of only none, one or two arguments. More argments that that need intermediate binder objects. All of this to avoid constant recoding of low-level stuff.

With C++ you stay with creating derived objects that are manipulated using base class pointers. Derived methods not in the base class are executed by using a Visitor. Derived objects that are modified notify a Mediator who sends messages to the necessary Obervers.
Apr 19 '09 #4

Sign in to post your reply or Sign up for a free account.

Similar topics

10
2253
by: forgotten field | last post by:
Hi,how are you? I have been studying C++ by myself, but recently I am having a real problem. I am learning about the basic usage of a doubly linked list using polymorphism. However, I have got the compiler errors which I just can't understand what they mean. I searched the webs for any clues on how to solve the problems. But I've never been...
6
6532
by: Litron | last post by:
This question borders between HTML and JS. I would like to have one ALT tag for a Button (IMG src link) when the user creates an onMouseOver event and a second Alt tag displayed onMouseOver if that page is already current in the browser. Can I assign the ALT tag text to a global variable and change the value of the global variable when...
3
5548
by: Odd Bjrn Andersen | last post by:
Every night at 21.30 we perform a full offline database backup. Just before the backup starts we do a db2stop/db2start. After the db2stop there is a message in the db2diag.log, and after the backup there is another message. And this happens every time. Here is an extract of the db2diag.log: 2004-03-01-21.30.38.812504 Instance:db2bpu1 Node:000 ...
2
1019
by: Daniel | last post by:
Hi, I heard that some free component needs to do dynamic linkage to the component library in order to avoid the LGPL / copyright. So, what is dynamic linkage and how to do it?? Any guidelines? Thank you in advance. Best regards,
3
1639
by: Richard | last post by:
I need to dynamically allocation memory at run time for the number of student's records and their test scores for the program code below. I don't understand what the 3 errors i got. I can anyone help. # include <iostream> # include <string> using namespace std; // structure declaration struct student_record
2
1638
by: serge calderara | last post by:
Dear all, Technically, what dynamic web page really means. Is it simply due to the fact that the content can be change without recompiling the web application by simply changing for example data base fields ? thnaks for your clarification regards
669
25460
by: Xah Lee | last post by:
in March, i posted a essay “What is Expressiveness in a Computer Language”, archived at: http://xahlee.org/perl-python/what_is_expresiveness.html I was informed then that there is a academic paper written on this subject. On the Expressive Power of Programming Languages, by Matthias Felleisen, 1990....
5
4298
by: Guillermo Schwarz | last post by:
C++ers, I have programmed in C++ since 1991 and I probably created my best abstraction layers in C++ in those days. Since 2001 I've been programming in Java (at first against my will, then I realized the market was moving into Java) and I'm trying to reimplement in Java what I did back in those days. The problem I have is that I have a...
4
2280
by: ambikasd | last post by:
Hi, Can anyone tell me what is dynamic method dispatch? And in what scenario it is usefull?
0
7457
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, well explore What is ONU, What Is Router, ONU & Routers main...
0
7391
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language...
0
7651
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. ...
0
7802
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that...
1
7410
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For...
0
7746
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the...
0
5962
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development projectplanning, coding, testing, and deploymentwithout human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then...
0
4941
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert...
1
1010
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.