4

Coming from JavaScript and Python, I'm trying to understand the nuances and purpose around C++ class constructors.

In the example below, why is it allowed to initialize attributes without a constructor?

class MyClass {
public:
    int a = 1;
    int b = 2;
};

Does the default constructor include the above definitions/initializations? What is the difference to the following two examples?:

1.

class MyClass {
public:
    int a;
    int b;
    MyClass(){
        a = 1;
        b = 2;
    }
};
  1. JavaScript/Python style (Is this even possible?)
class MyClass {
public:
    MyClass(){
        // Some kind of variable declaration and definition like:
        // this.a = 1;
        // this.b = 2;
    }
};

To me having the option of initialization without a constructor sounds like an overkill and is confusing. In both Python and JavaScript one usually declares and initializes all variables from the constructor, and only from there only.

What is the best practice here?

4
  • 3
    Your last option is definitely not possible because C++ is a statically typed language and so needs to know what data a class will contain ahead of time. And since you can split out declaration and definition into separate files you cannot define new member variables in the constructor body Commented Sep 16, 2020 at 18:09
  • 2
    Semi-related: Other popular languages, such as Java and C# also have this feature (combining member declaration with default initialization), so whether or not it is confusing is very subjective Commented Sep 16, 2020 at 18:15
  • 1
    You are missing option 3 MyClass() : a(1), b(2) {} (using the initialization list) which is much better then your option 1 and pretty much equivalent to your option 0.. Commented Sep 16, 2020 at 18:15
  • python has dynamic types, you can write foo.x = 42; anywhere in the code to make foo have a member called x with value 42, thats not restricted to constructors Commented Sep 16, 2020 at 18:33

1 Answer 1

13

In the example below, why is it allowed to initialize attributes without a constructor?

Because C++11 specifically added that feature. See Member initialization.

Does the default constructor include the above definitions/initializations?

Yes. This code:

class MyClass {
public:
    int a = 1;
    int b = 2;
};

Is roughly (not exactly) equivalent to this code:

class MyClass {
public:
    int a;
    int b;

    MyClass() : a(1), b(2) {}
};

It is actually possible to use both forms of initialization at the same time, eg:

class MyClass {
public:
    int a = 1;
    int b = 2;

    MyClass() = default;
    MyClass(int a) : a(a) {}
};

Per Member initialization:

Non-static data members may be initialized in one of two ways:

  1. In the member initializer list of the constructor.

  2. Through a default member initializer, which is a brace or equals initializer included in the member declaration and is used if the member is omitted from the member initializer list of a constructor.

    If a member has a default member initializer and also appears in the member initialization list in a constructor, the default member initializer is ignored for that constructor.

The a member is not specified in the default constructor's member initialization list, so it will be initialized with its default value of 1 when a MyClass object is default constructed.

The a member is explicitly initialized in the converting constructor's member initialization list, so its default value of 1 will be ignored and it will instead be initialized with the caller-provided value when a MyClass object is constructed with an input value.

The b member is not specified in either constructor's member initialization list, so it will always be initialized with its default value of 2.

What is the difference to the following two examples?:

The first example is what you would have to do prior to C++11 (if you are not using the constructor's member initialization list, as shown above).

The second example is not legal in C++. You can't declare members dynamically, and certainly not from inside a constructor. They have to be declared statically in the class declaration itself.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.