473,836 Members | 1,537 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 6438
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
2321
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 able to find one. Now I am wondering if there is any website which tells people how to understand...
6
6544
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 certain conditions exist, therefore having the ALT Tag display dynamic messages...?
3
5570
by: Odd Bjřrn 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 PID:25106(db2stop2) Appid:none base_sys_utilities stopdbm Probe:911 Database manager is...
2
1031
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
1649
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
1654
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
26333
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. http://www.ccs.neu.edu/home/cobbe/pl-seminar-jr/notes/2003-sep-26/expressive-slides.pdf
5
4315
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 job offer for programming in C++, again!!!, and I don't know if I should take it. My problem is...
4
2291
by: ambikasd | last post by:
Hi, Can anyone tell me what is dynamic method dispatch? And in what scenario it is usefull?
0
9825
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, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
9673
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 synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
10859
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. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
9388
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 project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
0
6984
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 into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5653
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
5829
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
4463
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
3
3116
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

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.