Codemonkey uk has an interesting piece on the use of explicit initialiser and destroy member functions rather than allowing object lifetime to be managed by the constructor and destructor.
Codemonkey uk comes down on the right side of the argument, in my opinion; explicit initialiser methods are devil spawn.
The problem with classes that have a separate init method, no matter what it’s called, is that the class can exist at least two states; constructed and initialised. Add in explicit destruction and you have three states; constructed, initialised, destructed. The fact that there are different states means that the object is harder to write and harder to use. As a user of the object, you need to know what you can do in each state and you need to know what state the object is in. As a writer of the object you need to support these states internally you need to know which state the object is in and know what’s allowed in each state. This complicates the object and the use of the object and unnecessary complexity is the number one enemy of programming.
The arguments that Codemonkey uk’s friends use are all pretty weak and all stem from inappropriate use of objects.
Explicit initialisation and destruction prevent hidden constructon/destruction. Don’t ya just love the ol’ ‘my complexity is for performance’ excuse? If you don’t want to incur the performance hit of fully constructing your object, don’t construct it. Simple. Codemonkey uk hits the nail on the head with his response to their argument. If you have an object that can operate in two modes, make it two objects so that both are always fully constructed and the operations that you can do on each are always available. Then switch from one mode to the other by calling a method on the first object that returns you the second… If you are wary of accidentally constructing objects that are expensive don’t allow accidents to happen; know what you’re doing. Use language features such as
explicitsingle argument constructors to remove, forever, the ‘chance’ that an object might get constructed when you don’t want it to; use private, undefined copy constructors and assignment operators to prevent unexpected copying of objects. Program by intent, not by accident. When you create an object you accept whatever performance hit you’re going to take, in exactly the same way you do when you explicitly call the ‘init’ method. So, first argument for is rubbish ;)
Implementing constructors that can fail where use of exceptions is problematic. Simple answer to this one; an object factory. The factory effectively does everything that the constructor would do before calling the real (
private) constructor. The factory can do any checks it likes and report the failure any way it likes, but if it gives you an object, it’s a real object, fully constructed and ready to use, not some half baked blob.
Some complex memory management excuse. Yeah, right, whatever. ;) Placement new should solve the problem, you probably don’t need to get that complex most of the time. How does splitting construction and initialisation help?
In summary, in my opinion, none of the arguments hold water. Two stage object construction leads to more complicated code, both in the client of the object and in the object itself. Checking an internal state inside the object to see if you’re fully initialised is just poor design. Avoid it.