Jump to content
  • Advertisement

Archived

This topic is now archived and is closed to further replies.

AndreTheGiant

How handle Errors in Constructor?

This topic is 5309 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I feel dumb asking this because I should know the answer already. What is a good thing to do when your constructor encounters an error, for example a file could not be found? You obviously can''t return an error code like 0 or 1 and have the calling code check it, since constructors dont return anything. I guess you could pawn the potentially error-prone code off to a helper function, but that only delays the problem. For example:
Ctr() {
  if ( !loadFile("reaaaadme.txt") ) {
     // same problem here. what do you do with this error?

  }
}
Then of couse, there is exceptions with try and catch and all that. How does this work? If you throw and exception in the constructor, where do you catch it? Do you have have code in the catch that undoes any resource allocation that you did in the constructor before the error occured? What is the best thing to do?

Share this post


Link to post
Share on other sites
Advertisement
Usually you don't want to do anything that can fail in the constructor. Instead you call .Init() on your object right after constructing it in order to do anything that can fail. That way you can return an error message.

Otherwise, your other options are to try to do some sort of recovery within the constructor (create the file since it doesn't exist?) or leave the file pointer set to NULL and check it later before using it. If the code that uses the filepointer later finds that it is NULL then that code can return the error.

One other way that I just thought of is to pass the address of a variable, put your constructor's return into that and check its contents after constructing the object.

CMyObject::CMyObject(BOOL* pFailed)
{
if ( !loadFile("reaaaadme.txt") )
{ // same problem here. what do you do with this error?
*pFailed = TRUE;
}
}

BOOL bFailed = FALSE;
pMyObject = new CMyObject(&bFailed);
if(bFailed)
{
// Oh no, something failed in my object's constructor
}

[edited by - Igilima on January 7, 2004 5:32:42 PM]

Share this post


Link to post
Share on other sites
Don''t put any code in a constructor that can fail. Most reasons to put code in a constructor that can fail are for clean looking code. Unfortunately, most don''t put the parallel error handling code necessary outside the constructor (let alone anywhere else). If they did, they wouldn''t like the appearance and re-design the constructor. Keep your constructors thin and light. You never know when someone is going derive from them. And so on.

Happing Coding!

Share this post


Link to post
Share on other sites
Three options:

1) Don''t do anything in a constructor that can fail.

2) Include an checkError() member function like the C++ stream classes have and which must be called and checked after construction/method calls.

3) Throw an exception from the constructor. This is a clean way for serious problems.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Have you guys never heard of RAII?! Of course it is OK to put code in a constructor that can possibly fail! This is what exceptions are for. Exceptions are like error codes that come with their own descriptions (there is more to it than that, but let''s just compare it to the old C style of return codes). Instead of returning -1 for this error 3 for that error, you throw an exception. You can throw an exception from your constructor on failure and the caller can catch the exception and deal with it. Having to call a separate Init() function is redundant and ugly.

Share this post


Link to post
Share on other sites
Another thing you can do is make it possible for the object to go into a "zombie" or "error" state. So, the contructor doesn''t throw exceptions or anything, it pretends that everything is fine, but if it encounters an error, it goes into the zombie state. Then maybe the function has a getError() function, and it''s the owner''s job to call getError() to find out if anything went wrong. And, write all the functions of the object so that if it is in a zombie state, it still won''t cause an error (although it surely won''t do anything useful either).

But personally, I prefer writing an init function. This also avoids the whole construction order fiasco.

Share this post


Link to post
Share on other sites
The "zombie" thing mentioned is how the std library does it (at least the iostream part).


#include <fstream>

using namespace std;
ifstream file("somefile.txt");
// if somefile.txt doesn''t exist, do something

if(!file)
{
// toss an error or otherwise handle

}
else
{
// file is good use and close

file.close();
}



daerid | Legends | Garage Games | Spirit | Hapy | Boost | Python | Google
"Doomed to crumble, unless we grow, and strengthen our communication" - Maynard James Keenan, Tool

Share this post


Link to post
Share on other sites
I''ma touch worried that it took 3 posts for someone to mention exceptions.
As soon as a read the topic title its what i thought of right away, its the natural way to handle the problem where you need to signal an error without a return value.
With file opening and the STL zombie states make sense (and i''m sure the clever ppl who designed it can rest easy now i''ve agreed, heeh) but I''d say for most other critical (sp?) errors where normal operation can not be continued an exception is the best option.

Share this post


Link to post
Share on other sites

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!