When you create an object in C++, you have a choice of using an initializer list or not. If you use an initializer list, you can set all the values in the object at once. But if you don’t, you have to set them separately and since you might be working with large objects, that could get tedious. So we’re going to look at a way to initialize objects with initializer lists.
When using the initializer list syntax to initialize an object, you must use the curly braces, not parentheses. This is because the compiler interprets a variable declared outside of the initialization list as a constant expression, which means it’s evaluated at compile time. When the compiler evaluates the expression, it finds that the value is undefined, so it generates a warning.
The solution is to use curly braces.
#include
class Point {
public:
int x;
int y;
};
Point a = {1, 2}; // error
Point b = {1, 2}; // okay
Point c; // error, not initialized
Point d = {1, 2}; // error, not initialized
C++ uses the curly brace syntax for initialization lists to avoid having to specify all of the member variables. With the curly braces, you can specify the members of the class in any order. The following example shows how to use the curly brace syntax to initialize an object.
#include
class Person {
public:
int age;
string name;
int height;
};
Person p1 = {22, "RAM", 180}; // okay
Person p2 = {21, "Anil", 175}; // okay
Person p3 = {22, "Vijay", 185}; // okay
Person p4 = {22, "RAM", 180}; // error, not initialized
A few things to note here:
- First, this is a class with two public member variables.
- Second, we have a constructor that takes three arguments: the person’s age, name, and height.
- Third, we have a constructor that takes a single argument and sets the member variables to the values provided.
- Fourth, we have a default constructor that is private.
- Fifth, we have a destructor that is private.
- Sixth, we have a copy constructor that is private.
Constructing vector Objects
#include
#include
using namespace std;
int main()
{
using MyVector = vector;
MyVector vectorA( 1 );
cout << vectorA.size() << " " << vectorA[0] << endl;
MyVector vectorB( 1, 10 );
cout << vectorB.size() << " " << vectorB[0] << endl;
return 0;
}
When you first look at the code, it might not do what you think it will. A single int containing 0 will be used to Initialize the vectorA variable. It would be incorrect to think that it would contain a single single digit number.
In this case, we are asking for it to store a single variable because the first Parameter determines how many values the initial vector will be set up to store. You might expect a couple of values, 1 and 10, but what we have here is a single value, and that value is 10.
The default value of the vectorB variable is used to instantiate the members, rather than the value specified by the variable. The code in listing 2-6 uses an initializer list in conjunction with uniform initialization to create a vector that contains two elements.
Using Uniform Initialization to Construct a vector
#include
#include
using namespace std;
int main()
{
using MyVector = vector;
MyVector vectorA( 1 );
cout << vectorA.size() << " " << vectorA[0] << endl;
MyVector vectorB( 1, 10 );
cout << vectorB.size() << " " << vectorB[0] << endl;
MyVector vectorC{ 1, 10 };
cout << vectorC.size() << " " << vectorC[0] << endl;
return 0;
}
The size and value of the first element of each vector are shown in the console output. The first one has a single element and its value is 0, while the second one has a single element and its value is 10.
The first element of the third Vector is 1 and it contains two values and is constructed using uniform initialization. There is a value of 10 for the second element. This can cause a significant difference in the behavior of your programs if you don’t take particular care to make sure that the correct type of initialization is used with your types. A more explicit use of the initializer_list can be seen in the code in listing 2-7.
Explicit initializer_list Usage
#include
#include
using namespace std;
int main()
{
using MyVector = vector;
MyVector vectorA( 1 );
cout << vectorA.size() << " " << vectorA[0] << endl;
MyVector vectorB( 1, 10 );
cout << vectorB.size() << " " << vectorB[0] << endl;
initializer_list initList{ 1, 10 };
MyVector vectorC(initList);
cout << vectorC.size() << " " << vectorC[0] << endl;
return 0;
}
An explicit initializer_list is used in the code in Listing 2-7. It is important that you understand what the compiler is doing when you write code using uniform because there is usually little need to create initializer lists.