简体   繁体   中英

C++ Constructor Exception Handling

I am new to exception handling in C++, and recently I ran into a bit of an issue.

In my code I want to create an object and only one of them. I am interfacing with a library where I must provide inputs to the constructor. Here's what a call to the constructor would look like:

ObjectA my_object(param1, param2, param3);

My issue is that the constructor itself can throw exceptions. I have done limited work with exceptions in the past (I know about the try-catch mechanism), but I'm not sure what to do here due to variable scope. For example:

try {
  ObjectA my_object(param1, param2, param3);
}
catch {
  // don't worry I need to do more than this here, just an example...
  cout << "OMFG!" << endl;
  exit(EXIT_FAILURE);
}
// if code got here, everything with my_object is OK
my_object.Method1(param1);  // ERROR: my_object is out of scope!

Some help would be appreciated in a quick way that I can check for the object being constructed correctly. Thanks

Well, like this:

try {
  ObjectA my_object(param1, param2, param3);
  my_object.Method1(param1);
  // other work
}
catch (/* the exception that constructor can throw */ ){
   // error handling stuff
}

If the try block would be to big, move the code from it to another function.

If the number of actions is small, sometimes you do this:

try {
    ObjectA my_object(param1, param2, param3);
    my_object.Method1(param1);
}catch(...)
{exit(EXIT_FAILURE);}

Commonly, if the constructor can throw exceptions, there exists an alternative way to initailize without exceptions:

ObjectA my_object; //may or may not be valid by itself 
try {
    my_object = ObjectA(param1, param2, param3); //initialize and copy-construct
    //alternatively:
    my_object.open(param1, param2, param3);
}catch(...)
{exit(EXIT_FAILURE);}
my_object.Method1(param1);

Otherwise, the most recommended solution is this:

boost::optional<ObjectA> my_object; //make it OPTIONAL
try {
    my_object = ObjectA(param1, param2, param3); //initialize and copy-construct
}catch(...)
{exit(EXIT_FAILURE);}
my_object.Method1(param1);

(if you don't like boost, optional is pretty trivial to implement yourself if you know how placement new works)

If the optional thing is too intimidated, it's easily replicated via dynamic memory as well:

std::unique_ptr<ObjectA> my_object; //make it OPTIONAL
try {
    my_object.reset(new ObjectA(param1, param2, param3)); //initialize and copy-construct
}catch(...)
{exit(EXIT_FAILURE);}
my_object->Method1(param1);
void doStuff()
{
  ObjectA my_object(param1, param2, param3);
  my_object.Method1(param1); 
}

try {
  doStuff();
}
catch {
  // don't worry I need to do more than this here, just an example...
  cout << "OMFG!" << endl;
  exit(EXIT_FAILURE);
}

or simply put all the relevant statements inside the try block.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM