Hello.
Not so long ago I started to learn D3D11 and at the moment I'm swimming through "Beginning DirectX 11 Game Programming" book. I found one thing, which I'm curious about. Author said that constructor’s member initialize list can be more efficient and is better programming practice than letting a constructor do the job in default way.
My question is as in topic, is that way of initializing members really better ?
Constructing your members with initial values is always as good as or better than constructing your members with default values and then assigning them an "initial" value later.
Why?
(1) it's often less work (cpu cycles, memory)
(2) it's often less code... the most efficient code is code you don't write
(3) your invariants are never ever violated (the object is never in an invalid state)
(4) some kinds of members, eg. references, must be initialized using an initializer list, so just do them all that way for consistency
There are some coding standards, such as the famous Google guidelines, that discourage you from initializing member variables using initializer lists. Such standards generally forbid the use of other features introduced into the language in the early 1990s and were obviously written either by a summer student or someone trying hard to sabotage the use of C++ in their organization to the benefit of their own religious language fervour. You should aim not to be one of those people.
Stephen M. Webb
Professional Free Software Developer
Not just references, but also inherited classes must be constructed in initializer lists: SubClass::SubClass(int blah) : BaseClass(blah) { }
With C++11 you can use "constructor delegating" (to call one constructor from another constructor) - this must also be done by initializer lists: class MyClass()
{
public:
MyClass() : MyClass("Unnamed", 5ft + 9in, BrownColor, 160lbs) {}
MyClass(std::string name, Color eyeColor) : MyClass(name, 5ft + 9in, eyeColor, 160 lbs) {}
MyClass(std::string name, int height, int weight) : MyClass(name, height, BrownColor, weight) {}
MyClass(std::string name, int height, Color eyeColor, int weight) : name(name), height(height), eyeColor(eyeColor), weight(weight) {}
}
[size=2]The above is C++11 specific code.
How-so ever! Also in C++11, you get 'Non-static data member initializers'. *squeals with joy*
This will allow you to do this instead: class MyClass()
{
public:
MyClass() : {}
MyClass(std::string name, Color eyeColor) : name(name), eyeColor(eyeColor) {}
MyClass(std::string name, int height, int weight) : name(name), height(height), weight(weight) {}
MyClass(std::string name, int height, Color eyeColor, int weight) : name(name), height(height), eyeColor(eyeColor), weight(weight) {}
private:
std::string name = "Unnamed"; //I get to do default initialization right in the class body! Sweet!
int height = 5ft + 9in;
int weight = 160lbs;
Color eyeColor = BrownColor;
}
@Servant of the Lord: you should prefix literals with an underscore, as literal suffixes not starting with an underscore are reserved for future use. But thanks for reminding me that they exist!
Most modern compilers will optimize the trivial stuff. So I only stick important things (large items, parent classes, references, ect...) in the initializer list, as I really don't like them. My big issue is that the order items are initlialized in the initializer list is not the same order as they are listed. Which for dependent items can really lead to some hard to track down bugs.
My big issue is that the order items are initlialized in the initializer list is not the same order as they are listed. Which for dependent items can really lead to some hard to track down bugs.
Ah, but should initialisation be in the initialiser list order, or the order you declared them in the class declaration?
FWIW many coding standards suggest keeping your initialiser lists in the same order as your member declarations for exactly this reason.
[quote name='Ryan_001' timestamp='1349347882' post='4986714']
My big issue is that the order items are initlialized in the initializer list is not the same order as they are listed. Which for dependent items can really lead to some hard to track down bugs.
Ah, but should initialisation be in the initialiser list order, or the order you declared them in the class declaration?
FWIW many coding standards suggest keeping your initialiser lists in the same order as your member declarations for exactly this reason.
[/quote]
Their order in the class definition is either for readability/clarity, or compactness/cache coherency. No one orders their variables in intialization order, at least, no one outside of C++. Not to mention dependencies can change based on the constructor that is chosen. If the order of initialization occurs in order of the intialization list, then at least you have some control in regards to dependencies. Course IMO the best solution is just to use intializtion lists when absolutely necessary, use standard C++ code the rest of the time.
[quote name='Ryan_001' timestamp='1349347882' post='4986714']
My big issue is that the order items are initlialized in the initializer list is not the same order as they are listed. Which for dependent items can really lead to some hard to track down bugs.
Ah, but should initialisation be in the initialiser list order, or the order you declared them in the class declaration?
FWIW many coding standards suggest keeping your initialiser lists in the same order as your member declarations for exactly this reason.
[/quote]
That, and because the language standard clearly and unambiguously specifies that member data is initialized in the order of declaration regardless of the order in which they appear in initializer lists. If there is a compiler that does not issue a warning when you put initializers out of order, you should switch to one that does. If you ignore the warnings the compiler gives you, blame only yourself.
If your coding standards suggest you write bad code, consider dropping that standard.
Consider also that if other people have to maintain your code, and they have become used to good practices such as initializing all member data in initializer lists, then you increase the maintenance cost of your software.
Stephen M. Webb
Professional Free Software Developer