Up until now, we’ve been initializing our class member data in the constructor using the assignment operator. For example:
class Something
{
private:
int m_nValue;
double m_dValue;
int *m_pnValue;
public:
Something()
{
m_nValue = 0;
m_dValue = 0.0;
m_pnValue = 0;
}
};
When the class’s constructor is executed, m_nValue, m_dValue, and m_chValue are created. Then the body of the constructor is run, where the member data variables are assigned values. This is similar to the flow of the following code in non-object-oriented C++:
int nValue; double dValue; int *pnValue; nValue = 0; dValue = 0.0; pnValue = 0;
While this does not exhibit good style, it is valid within the syntax of the C++ language.
So far, the classes that we have written have only included non-const or pointer member variables. However, what happens when we want to use const or reference variables as member variables? As you have learned in previous lessons, const and reference variables must be initialized on the line they are declared. Consider the following example:
class Something
{
private:
const int m_nValue;
public:
Something()
{
m_nValue = 5;
}
};
This produces code similar to the following:
const int nValue; // error, const vars must be assigned values immediately nValue = 5;
Consequently, assigning const or reference member variables values in the body of the constructor is not sufficient.
Initialization lists
C++ provides another way of initializing member variables that allows us to initialize member variables when they are created rather than afterwards. This is done through use of an initialization list.
In the lesson on basic addressing and variable declaration, you learned that you could assign values to variables in two ways: explicitly and implicitly:
int nValue = 5; // explicit assignment double dValue(4.7); // implicit assignment
Using an initialization list is very similar to doing implicit assignments.
Let’s take a look at our top example again. Here’s the code that does explicit assignments in the constructor body:
class Something
{
private:
int m_nValue;
double m_dValue;
int *m_pnValue;
public:
Something()
{
m_nValue = 0;
m_dValue = 0.0;
m_pnValue = 0;
}
};
Now let’s write the same code using an initializer list:
class Something
{
private:
int m_nValue;
double m_dValue;
int *m_pnValue;
public:
Something() : m_nValue(0), m_dValue(0.0), m_pnValue(0)
{
}
};
The initialization list is inserted after the constructor parameters, begins with a colon (:), and then lists each variable to initialize along with the value for that variable separated by a comma. Note that we no longer need to do the explicit assignments in the constructor body, since the initializer list replaces that functionality. Also note that the initialization list does not end in a semicolon.
Here’s an example of a class that has a const member variable:
class Something
{
private:
const int m_nValue;
public:
Something(): m_nValue(5)
{
}
};
We strongly encourage you to begin using this new syntax (even if you aren’t using const or reference member variables) as initialization lists are required when doing composition and inheritance (subjects we will be covering shortly).
10.2 — Composition
|
Index
|
9.12 — Shallow vs. deep copying
|
Constructing a website is not that different from building construction. Both code and home inspection are necessary to make sure all features are up to speed, and uniform building code is present in each to ensure consistency and quality.
10.2 — Composition
Index
9.12 — Shallow vs. deep copying
Hi Alex,
Just a question, can you use initialisation lists with arrays of members? something like this:
class Something { private: const int m_nValue[3]; public: Something(): m_nValue(5, 6, 7) { } };Or do you have to do it like this:
class Something { private: const int m_nValue[3]; public: Something(): m_nValue[0](5), m_nValue[1](6), m_nValue[2](7) { } };Thanks,
Daniel
Unfortunately, neither of those work. This actually hits on one of the shortcomings of the C++ language — there is no way to initialize non-static array members in C++.
However, there is a reasonable workaround. Because this is a constant array, we know the value of the members will never change — so why even have one array per class object? It makes more sense to define m_nValue as a static member, so it will be shared by all class objects. That way they all reference the same one and you save memory. And there IS syntax to initialize static array members in C++:
class Something { private: static const int m_nValue[3]; public: Something() { } }; const int Something::m_nValue[] = {5, 6, 7}Thanks, Daniel