Is there any good resources to show the possible methods one could use in order to better handle errors that may occur during the class constructor call?

I know of the throw() and catch() method but, just wondering if there are more efficient or just plain better methods to use in order to deal with such situations.

Thanks

02-17-2009

brewbuck

Quote:

Originally Posted by cyreon

Is there any good resources to show the possible methods one could use in order to better handle errors that may occur during the class constructor call?

I know of the throw() and catch() method but, just wondering if there are more efficient or just plain better methods to use in order to deal with such situations.

Thanks

There are two standard methods.

1. If construction fails, throw an exception. This is normally the best method.

2. If for some reason you cannot throw an exception, split construction into two phases: construct, then initialize.

Code:

SomeObject a;
if(!a.Initialize(...))
{
// something went wrong
}

You'd do this if, for instance, you were targetting an environment that did not support exceptions. Or, if the main body of code is not exception-safe, you do not want to introduce exceptions that may cause logical errors or resource leaks.

The choice to not use exceptions is a serious choice. Once you have decided that your design will not use exceptions, this decision is very hard to reverse, because code will have been written without taking exception-safety into account. Make sure you are making the right decision at the outset, because it is extremely difficult to change it.

02-17-2009

matsp

Constructor calls can not "fail" in any other ways than by throwing an exception [and in some cases/systems, constructor calls are not allowed to fail at all - if a class has some further work that needs doing that may fail, that has to be done in a separate method, after the class has been constructed - this would mean for example not calling new].

Since constructors in themselves can not return an error, the constructor can not inform the calling code about it's "succes" or "failure". And it is also a case of clean-up. If, for example, a constructor "returns" before the construction is finished, how does the object get cleaned up?
--
Mats

02-17-2009

cpjust

Quote:

Originally Posted by matsp

Constructor calls can not "fail" in any other ways than by throwing an exception [and in some cases/systems, constructor calls are not allowed to fail at all - if a class has some further work that needs doing that may fail, that has to be done in a separate method, after the class has been constructed - this would mean for example not calling new].

Since constructors in themselves can not return an error, the constructor can not inform the calling code about it's "succes" or "failure". And it is also a case of clean-up. If, for example, a constructor "returns" before the construction is finished, how does the object get cleaned up?
--
Mats

Sure you can return a success or failure in a constructor, you just have to do it with a parameter. Ex.

That's the cousin of the Initialize() method I showed above. Both have serious drawbacks. The fundamental problem is how to deal with the members that DID construct successfully. If these members are held by value, you have two options to destruct them, both of which suck:

1. Call Something::~Something() on yourself. This is wrong, because the object was never fully constructed in the first place.

2. Explicitly invoke the destructors of the completely constructed members. Gag me. They'll be double-destructed when the Something object goes out of scope, which it will do very soon, since it is invalid.

The workaround is to hold all members dynamically by pointer. Now you're doing really stupid stuff just because you have to avoid throwing inside a constructor. The bottom line is, if you have this restriction, life blows.

02-18-2009

cyreon

This question seems to have opened up a discussion, thanks for all of your input. I'm not sure if perhaps I am doing things wrong, but in the case of construction failure I do end up calling the deconstructor to destroy it, however, my deconstructors are built in a fashion that they verify data entries prior to releasing them and thus only what has already been initialized/created will be removed and those items that failed on creation will not even be touched. Is this something that I shouldn't be doing?

02-18-2009

laserlight

Quote:

Originally Posted by cyreon

my deconstructors are built in a fashion that they verify data entries prior to releasing them and thus only what has already been initialized/created will be removed and those items that failed on creation will not even be touched. Is this something that I shouldn't be doing?

How can you "verify data entries" such that "those items that failed on creation will not even be touched" unless all your data members are pointers? That is what brewbuck was talking about in the latter part of post #5.

02-18-2009

cyreon

Okay to rephrase, not all members are pointers such that some are simple data members (such as a DWORD, int, etc.) that signifies specific things to the class itself. Though the items to be initialized are infact pointers, I do not understand why this is termed as "doing really stupid stuff". Since a class Deconstructor is called just prior to the main entity being destroyed, is its main purpose not to remove all items that should infact be "cleaned up" (such as dynamic memory chunks)?

Sorry I've done a lot of C programming but, still grasping all the concepts of C++. Perhaps I have missed something in regards to the Deconstructor... if my opinions are wrong then would anyone have an example of a constructor/deconstructor (from any class) that would show a good example of their true purposes to a class? I am going to do some research on my own to read a bit more about this topic... and pull out the books. lol... now you have me wondering.

02-18-2009

matsp

Quote:

Originally Posted by cpjust

Sure you can return a success or failure in a constructor, you just have to do it with a parameter. Ex.

Yes, I have used this method (or one similar to it) for a work-project which had constructors that returned in case of errors - it was not a good solution, but it was the only solution that didn't involve redesigning an entire class - which would be the right thing to do in the long term.

And that code looked something like this:

Code:

Something s(ok)
if (ok)
{
... bunch of code ...
}

The reason the constructor woudl fail was that it called a non-throwing new to set a member pointer, and if the result was NULL it returned. The rest of the code, prior to my change, would then try to use the pointer, even when it was NULL - and other members that weren't initialized at all!