Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I check the failure in constructor() without using exceptions?

All of the classes that I'm working on have Create()/Destroy() ( or Initialize()/Finalized() ) methods.

The return value of the Create() method is bool like below.

bool MyClass::Create(...);

So I can check whether initialization of the instance is successful or not from the return value.

Without Create()/Destroy() I can do the same job in constructor() and destructor() but I can't solve below problem.

Can anyone help me? Thanks in advance.

I cannot use exceptions because my company doesn't like it.

class Foo
{
private:
    AnotherClass a;
public:
    Foo()
    {
        if(a.Initialize() == false)
        {
            //???
            //Can I notify the failure to the user of this class without using exception?
        }
    }
    ...
};

Foo obj;
like image 266
CodingLab Avatar asked Dec 23 '09 06:12

CodingLab


3 Answers

If you don't want to use exceptions, there are two ways to let the caller know whether the constructor succeeded or not:

  1. The constructor takes a reference/pointer to a parameter that will communicate the error status to the caller.
  2. The class implements a method that will return the error status of the constructor. The caller will be responsible for checking this method.

If you go with either of these techniques, make sure your destructor can handle an instance where the constructor has failed.

like image 199
R Samuel Klatchko Avatar answered Oct 26 '22 21:10

R Samuel Klatchko


C++ without exceptions is essentially a completely different language to C++, in which many of the idioms that give C++ its uniquely expressive power are rendered impotent. As you point out, constructors are stripped of their usefulness, and all nontrivial initialisation must be moved into a second-stage pseudoconstructor that can return an error indication. (Some people also advocate a matching pseudodestructor out of a misguided sense of symmetry, but that is completely pointless). Alternatively, the constructor could set a "constructed" flag on success, and each class could have a "constructed" method which checks this and all of its children.

If your company mandates that you disable exceptions, then you will also need a company-wide (or at least project-wide) convention to replace it. You will need to define a type for all (non-trivial) functions to return, and use that consistently everywhere - otherwise you'll get an unmaintainable hodge-podge of booleans and incompatible enumerations being passed around and manually converted at every level.

In this case, Foo will also need an Initialize method, which calls a.Initialize and bails out if that fails.

like image 5
Mike Seymour Avatar answered Oct 26 '22 19:10

Mike Seymour


There is not a good way; this is one of the major reasons they were added to the language in the first place. Without exceptions either:

  1. Perform some sort of assert() in the constructor to halt execution; impossible to ignore, but impossible to recover from.
  2. Do your actual construction in an Init function.
  3. ... or keep it within the constructor but set a "bad" flag.

Personally, I think 2 is strictly better than 3, as it doesn't increase class size, and makes it more visible when the "check" function isn't called. There are reasons I hear quoted, like you can access virtual functions, but I have always considered that to be fairly weak.

like image 3
Todd Gardner Avatar answered Oct 26 '22 20:10

Todd Gardner