HOWTO · C++

C++ Struct Default Values Initialization

Learn how to declare default values for C++ struct members and override them for individual objects with a constructor initializer list.

On this page

Declare a member default inside the struct definition with a brace-or-equal-initializer, such as int age = 30;. An object uses that value when its construction does not provide another initializer for the member. A constructor can provide an object-specific value in its member-initializer list while other members continue to use their declared defaults.

What default member initializers do

A default member initializer is attached to a data member in the type definition. It gives that member a value during construction when the constructor does not explicitly initialize it. This lets a simple data type provide useful defaults without adding a constructor whose only purpose is assigning those values.

The initializer applies whenever construction leaves that member to its default. It does not force every object to have the same value: a constructor may choose a different value for a particular object. A default member initializer participates in initialization; it is not an assignment that runs after the object has been built. Members without a default member initializer still need to be initialized by the constructor or another applicable initialization form before their values are read.

Set default member initializers

Write each initializer in the member declaration, inside the braces of the struct. C++ permits either an equals initializer, such as int age = 30;, or a braced initializer, such as int age{30};. Choose the form that fits the member’s type and your style, and keep each declaration terminated with a semicolon.

The closing brace of the struct definition is followed by a semicolon. Do not put a comma after the final member declaration. These punctuation marks belong to different parts of the definition: member declarations end with semicolons, and the type definition ends with };.

Override defaults when creating an object

When a constructor initializes a member in its member-initializer list, that value is used for that object instead of the member’s declared default. The initializer list names the members after the constructor’s colon, for example explicit Person(int a) : age(a) {}. Members omitted from the list can still use their default member initializers.

This behavior is useful when most objects should share sensible defaults but some need values from input or application state. A constructor should initialize the members that its parameters control; the defaults remain useful for any other members. If every member is always supplied at construction, the defaults may be unnecessary, but keeping them can still support other construction forms that leave a member to its default.

Rules and a complete example

A C++ struct is a type whose members and base classes are public by default; it is still a type used to create objects. A struct can also contain member functions and participate in inheritance. These properties do not change how member defaults work: the default is declared alongside the member, and a constructor initializer-list value takes precedence for the member it initializes.

Run this example:

#include <iostream>
#include <string>

struct Person {
    std::string name = "John Doe";
    int age = 30;

    Person() = default;
    explicit Person(int a) : age(a) {}
};

int main() {
    Person defaultPerson;
    Person namedPerson(25);

    std::cout << defaultPerson.name << ", " << defaultPerson.age << '\n';
    std::cout << namedPerson.name << ", " << namedPerson.age << '\n';
}
John Doe, 30
John Doe, 25

In the supplied successful run, the first object uses both declared defaults; the second receives age 25 from its constructor, while its name keeps the declared default.