Variable assignment and initialization in C++
Initialization
One downside of assignment is that it requires at least two statements: one to define the variable, and one to assign the value.
These two steps can be combined. When a variable is defined, you can also provide an initial value for the variable at the same time. This is called initialization. The value used to initialize a variable is called an initializer.
Initialization in C++ is surprisingly complex, so we’ll present a simplified view here.
There are 4 basic ways to initialize variables in C++:
You may see the above forms written with different spacing (e.g. int d{7};
). Whether you use extra spaces for readability or not is a matter of personal preference.
When no initialization value is provided (such as for variable a above), this is called default initialization. In most cases, default initialization leaves a variable with an indeterminate value. We’ll cover this case further in lesson (1.6 -- Uninitialized variables and undefined behavior).
When an initializer is provided after an equals sign, this is called copy initialization. Copy initialization was inherited from the C language.
Much like copy assignment, this copies the value on the right-hand side of the equals to the variable being created on the left-hand side. In the above snippet, variable width
will be initialized with value 5
.
Copy initialization is not used much in modern C++. However, you may still see it in older code, or in code written by developers who learned C first.
When an initializer is provided inside parenthesis, this is called direct initialization.
Direct initialization was initially introduced to allow for more efficient initialization of complex objects (those with class types, which we’ll cover in a future chapter). However, like copy initialization, direct initialization is not used much in modern C++ (except for one specific case that we’ll cover when we get to it).
The modern way to initialize objects in C++ is to use a form of initialization that makes use of curly braces: brace initialization (also called uniform initialization or list initialization).
Brace initialization comes in three forms:
Brace initialization has an added benefit: it disallows “narrowing conversions”. This means that if you try to brace initialize a variable using a value that the variable can not safely hold, the compiler will produce an error. For example:
In the above snippet, we’re trying to assign a number (4.5) that has a fractional part (the .5 part) to an integer variable (which can only hold numbers without fractional parts).
Copy and direct initialization would simply drop the fractional part, resulting in the initialization of value 4 into variable width (your compiler may produce a warning about this, since losing data is rarely desired). However, with brace initialization, the compiler will generate an error instead, forcing you to remedy this issue before proceeding.
Conversions that can be done without potential data loss are allowed.
Comments
Post a Comment