Does the defaulted default constructor initialize variables to zero?
Asked Answered
H

3

22

I'm updating a class to C++14, and trying to figure out the simplest way to initialize all of the instance variables to zero on construction. Here's what I have so far:

class MyClass {
public:
    int var;
    float* ptr;
    double array[3];
    MyStruct data;
    unique_ptr<MyStruct> smart_ptr;

    MyClass() = default;
    ~MyClass() = default;
}

Is setting the constructor to default the equivalent of doing:

MyClass() : var{}, ptr{}, array{}, data{}, smart_ptr{} {}

... or do I need to init each variable? (I've tried both in Visual Studio and I get zeros either way, but I'm not sure if that's luck or not.)

I'm instancing the class without brackets: MyClass obj;

Helluva answered 5/2, 2017 at 5:50 Comment(3)
Man, I was going to give you smug answer but now I'm not certain. See also #2417565Northeast
Hahah :) I know, right! I actually saw that post, but it was really this comment that left me feeling uncertain: #2417565. So it zero-inits if you don't have a constructor at all, and call MyClass instance() with brackets? :|Helluva
Logically, setting a constructor to default would be expected to default-initialise members. Default-initialisation is not always equivalent to zero-initialisation.Heder
T
19

Is setting the constructor to default the equivalent of doing:

MyClass() : var{}, ptr{}, array{}, data{}, smart_ptr{} {}

No. It is not.


The line

MyClass() = default;

is more akin to but not exactly equivalent to:

 MyClass() {}

In either case, using

 MyClass obj;

results in a default-initialized object whose members are default initialized.

However, the difference between them when using

 MyClass obj{};

is that obj will be zero-initialized with the defaulted default constructor while it will be still default initialized with the user provided default constructor.

Tarsus answered 5/2, 2017 at 6:25 Comment(4)
typo: int{} should be var{}Fleshpots
Fixed, thanks! I appreciate your answer, too. Am I right in thinking that MyClass() {} is a user-provided constructor, whereas MyClass = default; is a default constructor, so it would be zero-initialized in some circumstances? #26700220Helluva
@ChrisNolet "default constructor" means a constructor that can be called with no argumentsArezzo
Ahh, right you are, sorry. I meant defaulted constructor.Helluva
A
4

To make all of your variables zero-initialized on construction, even if the creator did not request it, one way is:

struct MyClassMembers
{
    int var;
    float* ptr;
    double array[3];
    MyStruct data;
    unique_ptr<MyStruct> smart_ptr;
};

struct MyClass : MyClassMembers
{
    MyClass(): MyClassMembers{} {}
};

Then MyClass m; will use MyClassMembers{} to initialize the members.

Arezzo answered 8/2, 2017 at 6:30 Comment(2)
unless one of the members has a non defaulted default constructor, as detailed in R Sahu's answerMccubbin
@Mccubbin I'm assuming that OP is fine with a member using its own constructor as definedArezzo
B
1

It is worth clarifying a few points. For a class with members as follows,

class MyClass {
public:
  int var;
  float* ptr;
  double array[3];
  MyStruct data;
  unique_ptr<MyStruct> smart_ptr;
  ...
}

A default constructor defined by the user as follows,

MyClass() : var{}, ptr{}, array{}, data{}, smart_ptr{} {}

will lead to value initialization of the member variables. If a member variable is a class type then its value initialization happens under certain conditions as described in that link.

While defining an object with or without braces (MyClass obj{}; or MyClass obj;), this default constructor will lead to value initialization of the class members.

Suppose, MyClass has a default constructor in one of the following forms:

MyClass() {};
MyClass() = default;

(See here about further information on these two forms for the default constructor.) As far as defining and initializing objects of MyClass is concerned, MyClass() {}; leads to default initialization, while MyClass() = default; leads to value initialization when defining an object with braces (MyClass obj{};). This is because MyClass() {}; is a user defined default constructor with an empty initialization list and an empty body, which will lead to default initialization of the members. On the other hand, MyClass() = default; leads to a compiler defined default constructor, which will correctly lead to value initialization when defining an object with braces. See here about how even the = default; could go wrong.

Brahman answered 28/3, 2023 at 18:58 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.