Initialize in constructor or in a separate function?

Started by
24 comments, last by jwein 14 years ago
Hello, I would like to ask you a suggestion about generic programming and software architecture. Do you think it's better to initialize an object in its constructor or in a separate Initialize() method of the class? If I have, for example, a Renderer class, which represents a wrapper for the Directx API, should I initialize Directx in the constructor or in a separate function? Is there a generic rule to choose between the two? Thank you :-) [Edited by - jwein on March 19, 2010 3:22:47 PM]
Advertisement
In the constructor. That's what it is there for.

There may be rare cases where this is not appropriate and you need to provide for deferred initialization. I find those cases to be extremely rare in otherwise well-designed systems (they may be less rare in poorly designed systems). So... in almost all cases, the constructor is where object initialization logic should be.
Thank you for the answer. Can I ask you if there is a particular motivation or advantage in initializing in the constructor?
You can only initialize in the constructor, and in C++ you can only initialize in the initializer list:

struct Foo {    const bool hello;    int world;    int how_is_it;    Foo () : hello(true), world(0xDeadFeed) // initialization    {        how_is_it = 42; // assignment    }};


It often yields the same results, thanks to optimization. But some entities, like the const-bool in the example, can only be initialized, not assigned. Initialization is always prefereable, sometimes to the degree that you should better write static helper functions instead of doing assignment (E.g.:

struct Foo {    const bool hello;private:    static bool aComplexDecision(int x) {        ...    }public:    Foo (int x) : hello(aComplexDecision(x)) {}};
Quote:Original post by jwein
Thank you for the answer. Can I ask you if there is a particular motivation or advantage in initializing in the constructor?


There are a few good reasons for this. First, think about logical state. An object doesn't exist until it is constructed. If you initialize during construction, you ensure that the object doesn't start out in an invalid state, so it reduces the chances of bugs.

This is also a very useful paradigm for multithreaded code. If you have an object shared between threads, there's no chances of two different threads accessing the object before it is initialized if you initialize during construction, because you can't reference the instance until after.
If you place initialization code in a separate function, then there is a time between object construction and calling this function. During this time, the object is in a kind of intermediate state, that is, it is not usable. If you avoid this, your code becomes cleaner and simpler.
I know, but I was referring to the initialization of the class from another point of view.

For example I didn't know where to call D3D10CreateDeviceAndSwapChain, which is supposed to initialize some members of the class, and so on...
Ah ok, now I understand. It's true... Thanks :-)
I like the option for both.

Consider this example from the standard library.

File streams can be created with no parameters. In this case it creates an object that is an unopened stream. You can call open() directly on it later. You also have the option of calling close() on it and then open() with a different file.

They also have a constructor that takes a file name. In that case you get an opened stream. If there is a problem opening the file, however, you must deal with it at construction time. The destructor is similar: If the file is still open the destructor will close it, but if there is a problem writing the last little bit of the file, you won't know about it because destructors don't/shouldn't throw.


If your code requires that kind of initialization in construction, it can make for slow constructors. If your constructor can throw exceptions, it can make for complicated logic. If you don't provide a default constructor you cannot use the class in a container.
Quote:Original post by frob
If you don't provide a default constructor you cannot use the class in a container.

Of course you can, std::vector does not require default construction for example.

This topic is closed to new replies.

Advertisement