C++ 类:在没有构造函数重载的情况下初始化属性

Mic*_*l H 2 c++ constructor class constructor-overloading default-constructor

来自 JavaScript 和 Python,我试图了解 C++ 类构造函数的细微差别和目的。

在下面的示例中,为什么允许在没有构造函数的情况下初始化属性?

class MyClass {
public:
    int a = 1;
    int b = 2;
};
Run Code Online (Sandbox Code Playgroud)

默认构造函数是否包括上述定义/初始化?下面两个例子有什么区别?:

1.

class MyClass {
public:
    int a;
    int b;
    MyClass(){
        a = 1;
        b = 2;
    }
};
Run Code Online (Sandbox Code Playgroud)
  1. JavaScript/Python 风格(这甚至可能吗?)
class MyClass {
public:
    MyClass(){
        // Some kind of variable declaration and definition like:
        // this.a = 1;
        // this.b = 2;
    }
};
Run Code Online (Sandbox Code Playgroud)

对我来说,在没有构造函数的情况下进行初始化的选项听起来有点矫枉过正,而且令人困惑。在 Python 和 JavaScript 中,通常从构造函数声明和初始化所有变量,并且仅从构造函数开始。

这里的最佳做法是什么?

Rem*_*eau 8

在下面的示例中,为什么允许在没有构造函数的情况下初始化属性?

因为 C++11 专门添加了该功能。请参阅成员初始化

默认构造函数是否包括上述定义/初始化?

是的。这段代码:

class MyClass {
public:
    int a = 1;
    int b = 2;
};
Run Code Online (Sandbox Code Playgroud)

粗略(不完全)等同于以下代码:

class MyClass {
public:
    int a;
    int b;

    MyClass() : a(1), b(2) {}
};
Run Code Online (Sandbox Code Playgroud)

实际上可以同时使用两种形式的初始化,例如:

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

    MyClass() = default;
    MyClass(int a) : a(a) {}
};
Run Code Online (Sandbox Code Playgroud)

每个成员初始化

非静态数据成员可以通过以下两种方式之一进行初始化:

  1. 在构造函数的成员初始值设定项列表中。

  2. 通过默认成员初始值设定项,它是包含在成员声明中的大括号或等号初始值设定项,并且在构造函数的成员初始值设定项列表中省略该成员时使用。

    如果成员具有默认成员初始值设定项并且还出现在构造函数的成员初始化列表中,则该构造函数的默认成员初始值设定项将被忽略。

a成员未在默认构造函数成员初始化列表中指定,因此当MyClass默认构造对象时,它将以其默认值 1 进行初始化。

a成员在转换构造函数成员初始化列表中显式初始化,因此其默认值1将被忽略,而当MyClass使用输入值构造对象时,它将使用调用者提供的值进行初始化。

b成员未在任一构造函数的成员初始化列表中指定,因此将始终使用其默认值 2 进行初始化。

下面两个例子有什么区别?:

第一个示例是您在 C++11 之前必须执行的操作(如果您没有使用构造函数的成员初始化列表,如上所示)。

第二个例子在 C++ 中是不合法的。您不能动态声明成员,当然也不能从构造函数内部声明。它们必须在类声明本身中静态声明。