c++initializationzeroidiomsconstruction

Idiom to initialize C++ class to zero


Consider the following C++ class:

struct Point
{
    int x;
    int y;

    explicit Point() =default; // 1
    explicit Point(int x_, int y_): x(x_), y(y_) { } // 2
};

The second constructor is useful for creating a Point with specific x and y values. The first exists so that I can default construct a Point. However, for efficiency, it is defaulted and does not set x and y to zero. If I did want to set all members to zero, I could have another constructor:

explicit Point(int val) : x(val), y(val) { } // 3

This way, I can choose to either default initialize the Point, or initialize it with all members being set to zero:

Point p1;    // Don't initialize members.
Point p2(0); // Initialize all members to zero.

The problem with the third constructor is that I can really pass any value, not just zero. For example:

Point p(1); // Both x and y set to 1! Is this the intent? If so,
            // probably should have used Point p(1, 1) instead.

Another way would be to have a special type which represents a zero or default value and pass that to the constructor:

explicit Point(Default) : x(0), y(0) { } // 4

Where Default can be defined simply as:

struct Default { };

Then, I can control when I want the Point to be initialized with default values:

Point p1;            // Don't initialize members.
Point p2(Default()); // Initialize members with default values.

Which method would be considered better, the method with the sentinel type Default (no. 4), or the constructor which takes a single value and initializes all members to that value (no. 3)? What are the pros/cons of the two methods? Or is there another better mechanism to do this?

Edit: Please note that this simple class was chosen for illustration; in reality, there might be many more members which need specific default values to be considered "initialized".


Solution

  • Make your life easier, make simple data structs like this aggregates:

    struct Point
    {
        int x;
        int y;
    };
    

    Now you can use aggregate initialization:

    Point p;      // members uninitialized
    Point p{};    // members set to 0
    Point p{1,2}; // members set to 1,2