Why use an initialization method instead of a constructor?

Viewed 47998

I just got into a new company and much of the code base uses initialization methods instead of constructors.

struct MyFancyClass : theUberClass
{
    MyFancyClass();
    ~MyFancyClass();
    resultType initMyFancyClass(fancyArgument arg1, classyArgument arg2, 
                                redundantArgument arg3=TODO);
    // several fancy methods...
};

They told me that this had something to do with timing. That some things have to be done after construction that would fail in the constructor. But most constructors are empty and I don't really see any reason for not using constructors.

So I turn to you, oh wizards of the C++: why would you use an init-method instead of a constructor?

12 Answers

A few more cases:

COOKING ARGS

A constructor can't call another constructor, but an init method can call another init.

For instance say we have a initializer that takes a list of conventional args. We have another initializer that takes a dictionary of name=value pairs. The second can query the dictionary for the arguments the first initializer accepts and call the first with them.

This is fine when the initializers are an init methods, but not when the initializers are constructors.

CHICKEN OR EGG

We might have a car class whose initializer must have a pointer to a motor object, and the motor class initializer must have a pointer to its car object. This is simply impossible with constructors, but trivial with init methods.

BREAKING UP ARG LIST

There may be a huge number of args that could be specified but don't need to be (perhaps the default values suffice, or perhaps some parameters are only needed depending on values for other parameters). We may wish to have several initializers instead of a single one.

Again, it's simply impossible to break up a constructor, but trivial to break up an initializer.

Another use case:

You have an object pool, like a simple vector of objects (not a vector of pointers, but actual stack allocated objects tightly packed).

The object class is complex, with many private member variables, which all needs to be set properly.

As such, each object is properly constructed upon insertion (using constructor, with many parameters).

So far, the init function is not in the picture, a constructor can do this so far.

Due to an external event, one of the object in the middle has to be:

  • removed from the pool, basically destroyed
  • and a new element has to be created with different parameters.

You don't want to do memory operation on that single element, like delete/new to invoke the constructor/destructor, that's expensive. What you want is dispose and reinitialize the existing objects fully, with the new parameters, so no reallocation occurs.

This can be done with getter setter functions for each variable, but that doesn't take care of the dispose part, also its very easy to leave out member variables from the list, and you end up partially setup object. Better to put together an init function which expects all the necessary parameters for its member variables, and reinitialize the whole object simply, over and over again, if needed.

Related