I was doing the reading, and it seems that the general consensus is that biphasic initialization should be avoided whenever possible. I agree with what he said. But I do not find it so easy to fix.
Here is a fully compiled example, although it is heavily based on some kind of real code -
Imagine I'm building a game. The main class of the game is to build a "RenderDevice" object that performs 3D rendering. But to create it, you need some parameters to load from the configuration file. And a Window object for drawing. Both the log object and the memory pool. My code now puts all these things as members of a class where the constructor does little, and then calls the init function for each object with the appropriate parameters, for example: -
// Much simplified code to make a point Game::Game() { memoryPool_.init(10000000); // Amount of memory to allocate logger_.init("logfile.txt", memoryPool_); window_.init(2000, 1000); // Make a nice big window renderDevice_.init(window_, logger_, memoryPool_); }
What seems to me to work quite well. But these are two phases. Each object is only partially constructed by the constructor. So I have to do something like this instead of making the code βcleanβ.
Game::Game() : memoryPool_(1000000), logger_("logfile.txt", memoryPool_), window_(2000, 1000), renderDevice_(window_, logger_, memoryPool) { }
Now this code looks pretty ugly to me, but also pretty fragile as the initialization order depends on the order they declare in the class, and not in the order specified here. As additional data is added to the class, it gets even worse. Objects here require only a few parameters, but if they need more data, it will quickly get out of hand.
The advantage is that every object is designed to do the job, but it looks ugly to me and seems rather fragile and error prone ...
So my question is: did I miss this? Is there a better way to do this? Should I stop worrying and just do it, or use the original code? Or is my design incorrect at a higher level in some way, and therefore the question is not useful?
Basically, what is best practice?