【问题标题】:C++ Classes: Initializing attributes without constructor overloadingC++ 类:在没有构造函数重载的情况下初始化属性
【发布时间】:2021-01-03 14:46:53
【问题描述】:

来自 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++ 是一种静态类型语言,因此需要提前知道类将包含哪些数据。而且由于您可以将声明和定义拆分为单独的文件,因此您无法在构造函数主体中定义新的成员变量
  • 半相关:其他流行的语言,如Java、C#也有这个特性(成员声明与默认初始化相结合),所以是否混淆是很主观的
  • 您缺少选项 3 MyClass() : a(1), b(2) {}(使用初始化列表),这比您的选项 1 好得多,并且几乎等同于您的选项 0..
  • python有动态类型,你可以在代码的任何地方写foo.x = 42;,让foo有一个名为x的成员,值为42,不限于构造函数

标签: c++ class constructor default-constructor constructor-overloading


【解决方案1】:

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

因为 C++11 专门添加了该功能。见Member initialization

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

是的。这段代码:

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) {}
};

Member initialization

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

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

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

    如果一个成员有一个默认的成员初始化器并且还出现在构造器的成员初始化列表中,那么该构造器的默认成员初始化器将被忽略。

default constructormember initialization list 中没有指定a 成员,因此在默认构造MyClass 对象时,它将使用其默认值1 进行初始化。

a 成员在converting constructormember initialization list 中显式初始化,因此其默认值1 将被忽略,而是在MyClass 时使用调用方提供的值进行初始化对象是用输入值构造的。

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

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

第一个例子是你在 C++11 之前必须做的事情(如果你没有使用构造函数的member initialization list,如上所示)。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-12
    • 1970-01-01
    • 1970-01-01
    • 2015-09-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多