Jump to content
  • Advertisement
Sign in to follow this  
jwein

Initialize in constructor or in a separate function?

This topic is 3020 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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]

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
Thank you for the answer. Can I ask you if there is a particular motivation or advantage in initializing in the constructor?

Share this post


Link to post
Share on other sites
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)) {}
};

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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...

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!