Used only inside constructors to initialize data members before the constructor body executes.
class Foo {
int b;
double c;
public:
Foo(int i, double j) : b(i), c(j) {}
};- Required for
constand reference members - Required for members without default constructors
- Avoids default‑construction + assignment
- Initialization order follows member declaration order, not list order
Aggregate initialization uses brace‑enclosed lists to initialize aggregates:
An aggregate is a type with:
- no user‑declared constructors
- no private or protected non‑static data members
- no virtual functions
- no base classes
struct S {
int i;
};
S s{10};This is aggregate initialization.
Conceptually equivalent to:
S s;
s.i = 10;but performed during initialization, not assignment.
S s = {10};Still aggregate initialization.
S s{3.14}; // compile‑time errorInitializes an object from another object or expression using =.
int a = 5;
int b = a;Triggers copy or conversion constructors when applicable.
Also occurs when:
void f(Foo x);
f(obj); // copy or move
Foo make();
Foo x = make(); // copy elided or movedInitializes an object directly, usually via a constructor.
Foo f(10);
std::string s("abc");
int x(5);Occurs when no initializer is provided.
int x; // indeterminate value
Foo f; // calls default constructor (if any)
new int; // indeterminateFor built‑in types: no initialization.
Forces zero‑initialization for fundamental types.
int x{}; // zero
int y = int(); // zero
Foo f{}; // default constructorCommon interview pitfall: T() ≠ default initialization.
Automatically applied in specific contexts:
- static storage duration
- thread‑local storage
static int x; // zeroAlso part of value initialization.
General brace‑based syntax applicable to everything.
int a{42};
std::vector<int> v{1,2,3};
MyClass m{1, 3.14};Benefits:
- prevents narrowing
- uniform syntax
- works for aggregates and constructors
Provides default values at declaration site.
class MyClass {
int x = 10;
double y{3.14};
};Used if constructor does not override them.
std::initializer_list enables custom brace handling.
class IntArray {
int size;
int* data;
public:
IntArray(std::initializer_list<int> list)
: size(list.size()), data(new int[size]) {
int i = 0;
for (int v : list) data[i++] = v;
}
};
IntArray a{1,2,3,4};This is list initialization via constructor, not aggregate initialization.
| Syntax | Meaning |
|---|---|
T x; |
default initialization |
T x{}; |
value initialization |
T x = y; |
copy initialization |
T x(y); |
direct initialization |
T x{y}; |
list initialization (aggregate or ctor) |
S s{10};is called:
- brace initialization
- specifically aggregate initialization
when S is an aggregate.
References:
- cppreference — initialization
- modernescpp.com
- C++ Core Guidelines