Sign in to follow this  
EAX

failing constructors

Recommended Posts

If the constructor in my class calls an initialization function to initialize things for that class, and the function returns an error, what would be the best way to tell my program that the class is unusable?

Share this post


Link to post
Share on other sites
I'm not sure how to use an exception that way


myClass::myClass()
{
int error;
error = failingFunction();
}

int main()
{
myClass *foo;
foo = new(myClass);
}




Would I put try and catch in main, and throw in the constructor or what?

Share this post


Link to post
Share on other sites
Quote:
Original post by EAX
I'm not sure how to use an exception that way

*** Source Snippet Removed ***

Would I put try and catch in main, and throw in the constructor or what?

Exceptions work the same no matter where they are thrown from. In this case, the constructor is being called from within main, so that is where you would catch it.

CM

Share this post


Link to post
Share on other sites
Id rather not have to put a try and catch for every new object.
Perhaps I should just not error check and assume everything will work right.

Or would that be a very bad idea?

Share this post


Link to post
Share on other sites
Quote:
In Which Eeyore Has a Birthday And Gets Two Presents by A. A. Milne:
"No," said Pooh. "That would not be a good plan.

Does it make sense for your program to continue if the object could not be constructed? Catch the exception at the level that makes sense:
class Level
{
public:
Level(std::string);
bool play();
Level nextLevel();
};

int main()
{
try
{
// if this throws there's not much point continuing so bail
Level level("level1.dat");
while (level.play())
{
level = level.nextLevel();
}
}
catch (...)
{
// apologise to user
}
}

Level::Level(std::string data)
{
// stuff
try
{
// if this fails there's something we can do about it straight away
// although it would be better to encapsulate this rather than
// having to keep writing try-catch blocks
prettyTexture = Texture("prettyTexture.jpg");
}
catch (...)
{
prettyTexture = dullBoringDefaultTexture;
}
}

Enigma

Share this post


Link to post
Share on other sites
Quote:
Original post by EAX
Id rather not have to put a try and catch for every new object.
Of course you shouldn't have a catch block for every object! You put the catch block at a higher level in the code. How high depends on how you want to handle errors.

It looks like you are are not familiar with the RAII idiom. I recommend that you use it — it makes C++ much easier. See here and here for more information.

Share this post


Link to post
Share on other sites
Quote:
Original post by Rocket05
just move the initialization routine call outside of the constructor and allow it to be called & checked by the calling code


Please don't do this; as it breaks the RAII idiom that Beer Hunter is talking about. You should attempt to use RAII whenever possible in C++. A seperate init function called after the constructor is run defeats the entire purpose of having a constructor; if initialization of the object fails, it shouldn't be created at all!

Share this post


Link to post
Share on other sites
The Factory pattern is a reasonable alternative sometimes, too:


// Some variation on this basic idea:

// Document the class to tell users how to get an instance:
// Foo* x = Foo::create();
// if (!x) { /* doh */ }
class Foo {
Foo(); // note, private!
bool init(); // Do actual setup and return whether successful.
~Foo(); // must be able to handle a badly-inited object.
public:
static Foo* create() {
Foo* x = new Foo();
if (!x.init()) {
delete x;
return null;
}
return x;
}
}




You could also make a wrapper for exception-throwing constructors in order to have just one place that the exception gets handled (which you can then still go around if you need special handling):


template <typename T>
// You can template this for a given number of args of whatever type, but
// unfortunately there is no way to template for an unknown number of arguments.
T* create() {
try { return new T; }
catch (...) { return null; }
}

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this