The code cleanup tool is right. This code doesn't do what you think it does:
void Init()
{
double array2D[10][10] = {0.0};
bool logicalarray[2] = {false};
}
You think that this code initializes MyClass
's member variables. What it actually does is declare two local (automatic) variables, initialize them, and then return. The member variables aren't touched, and are hidden within Init()
's body.
You could fix this by:
void Init()
{
array2D[10][10] = {0.0};
logicalarray[2] = {false};
}
But I would argue that this is technically correct but still wrong. You are using what's called two-phase construction. The two phases are: 1) Construct an MyObject
. 2) Initialize the MyObject
by calling it's Init()
function.
Ugly. Nasty. Prone to errors & forgetfullness. Semantically incorrect because the constructor doesn't leave the object in a fully initialized state. You should, as a general rule, avoid two-phase construction at all costs. A better way is to perform all initialization in the object's constructor -- preferably in a member initialization list, but this is difficult/impossible for aggregate members. In those cases, initialize in the constructor's body:
class MyClass
{
public:
MyClass ()
{
array2D[10][10] = {0.0};
logicalarray[2] = {false};
}
// ...
};
Now, construction of the MyObject
also means initialization of MyObject
. And after all, that's what constructors are for. Do that instead.
The problem here is that we can't initialize aggregates like this. We can only initialize an aggregate using this syntax at construction time, but that happened in the (non-existant) initialization list. We can't use an initialization list in C++03 to initialize an aggregate. So you're left with an ugly situation:
MyClass ()
{
memset (logicalarray, logicalarray+2, 0);
memset (array2D, array2D+sizeof (array2D), 0);
}
This leads me to an argument that you shouldn't be using raw arrays in the first place, but rather a vector
(or something) and initialize it via something like:
class MyClass
{
public:
std::vector <bool> mBools;
std::vector <std::vector <double> > mDoubles;
MyClass ()
{
std::fill_n (std::back_inserter (mBools), 2, false);
}
};
I'll leave initialization of mDoubles
as an exercise.