c++ - 使用初始化列表来初始化字段和在构造函数中初始化它们有什么区别?

标签 c++ class constructor constants initializer-list

在一些教程中(例如 http://www.tutorialspoint.com/cplusplus/cpp_constructor_destructor.htm),我读到以下两个代码是等效的。

第一个代码:

class MyClass1{
    public:
        int a;
        int b;
        MyClass1(int a, int b) : a(a), b(b) {};
};

第二个代码:

class MyClass2{
    public:
        int a;
        int b;
        MyClass2(int, int);
};

MyClass2::MyClass2(int a, int b){
    this->a = a;
    this->b = b;
}

事实上,他们给我的结果是一样的。但是,如果我使用 const 成员,我就不能再编译代码了。

class MyClass1{
    public:
        const int a;
        const int b;
        MyClass1(int a, int b) : a(a), b(b) {};
};

class MyClass2{
    public:
        const int a;
        const int b;
        MyClass2(int, int);
};

MyClass2::MyClass2(int a, int b){
    this->a = a;
    this->b = b;
}

事实上,第一个类没有给我任何错误,但第二个类中有一个只读成员的赋值。所以,这些是问题:

这两种初始化方法的真正区别是什么?

使用初始化列表是初始化类的 const 成员的唯一方法吗?

注:我在线阅读delegating constructors的使用以避免这个问题,但我不清楚它们的用途和它们的实际作用。

最佳答案

查看它的一种简单方法是与局部变量建立联系:

  1. 使用初始化列表等同于局部变量的这种观点:

    int a = 1;
    int b = 2;
    
  2. 第二种形式,在构造函数中分配它们等同于:

    int a;
    int b;
    
    a = 1;
    b = 2;
    

你可以看到对于 const 或没有默认构造函数的对象来说这可能是一个问题:

常量成员

  1. 好的:

    const int a = 1;
    const int b = 2;
    
  2. 不好:

    const int a;
    const int b;
    a = 1;
    b = 2;
    

具有已删除或不可访问的默认构造函数的类型

例如:

class X {
public:
   X() = delete; // default constructor deleted
   X(int){};     // constructor with an int parameter
};
  1. 好的:

    X x(1);
    
  2. 不好:

    X x;
    x = X(1);
    

第三个选项:In-class member initializers (since c++11)

class A {
public:
   const int a = 10;
};

关于c++ - 使用初始化列表来初始化字段和在构造函数中初始化它们有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33520679/

相关文章:

c++ - 使用C++11继承构造函数时如何初始化派生类成员?

c++ - Visual Studio 为新的初始化程序提供部分代码覆盖

c++ - 函数模板重载谜题

c++ - 如何编写一个可以在BitDefender下运行的没有窗口的程序?

c++ - 获取函数指针和类指针的函数?

python - 是否可以在 Python 中创建具有未知属性的类?

java - 调用一个方法但它不起作用

java - onLoad JSF 填充列表框

c++ - 模板函数参数

c# - 为什么 BaseController 的重载构造函数没有被执行?