首页 > 解决方案 > C++ 类:在没有构造函数重载的情况下初始化属性

问题描述

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

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

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

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

1.

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

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

这里的最佳做法是什么?

标签: c++classconstructordefault-constructorconstructor-overloading

解决方案


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

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

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

是的。这段代码:

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

大致(不完全)等同于这段代码:

class MyClass {
public:
    int a;
    int b;

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

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

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

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

每个成员初始化

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

  1. 在构造函数的成员初始化列表中。

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

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

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

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

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

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

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

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


推荐阅读