【问题标题】:Initialization lists,local variables vs data members初始化列表,局部变量与数据成员
【发布时间】:2012-09-29 09:04:43
【问题描述】:
#include <iostream>
using namespace std;
class Ex {
private:
    int i;
    float f;
public:
    Ex(int i,float f):i(i),f(f) {
        cout << this->i << '\t' << this->f << endl;
    }
    ~Ex(){
        cout << "destructor";
    }
};
int main() {
    Ex i(10,20.1f);
}

在我上面写的程序中,如果构造函数是参数化的构造函数,如下所示:

Ex(int i,float f){
        i=i;
        f=f;
        cout << this->i << '\t' << this->f << endl;
    }

这里对象的数据成员被初始化为垃圾,因为数据成员由于同名的局部变量而被隐藏。 但是在上面的程序中,没有明确的 this.How 可以正常工作?

【问题讨论】:

    标签: c++ oop constructor initialization


    【解决方案1】:

    编译器设计为使用左侧的if 作为类作用域的成员,使用右侧的if 作为构造函数作用域的成员。

    【讨论】:

    • 这不是编译器实现的细节。它是 C++ 标准所要求的。
    【解决方案2】:

    以前曾提出过类似的问题,例如herehere,但是虽然许多答案指出这(与 Konstantin D - Infragistics 所说的相反)不是特定于编译器的,但我找不到任何实际引用标准相关部分的答案。

    所以他们来了。我已经添加了重点以突出关键语句。

    (§12.6.2/10) 在非委托构造函数中,初始化按以下顺序进行:

    ——首先,并且仅对于最派生类 (1.8) 的构造函数,虚拟基类按照它们出现在基类的有向无环图的深度优先从左到右遍历中出现的顺序进行初始化,其中“从左到右”是派生类基说明符列表中基类的出现顺序。
    — 然后,直接基类按照它们出现在 base-specifier-list 中的声明顺序进行初始化(无论 mem-initializers 的顺序如何)。
    — 然后,非静态数据成员按照它们在类定义中声明的顺序进行初始化(同样与 mem-initializers 的顺序无关)。
    — 最后,执行构造函数体的复合语句。

    (§12.6.2/12) 内存初始化器的表达式列表或大括号初始化列表中的名称在内存初始化器所在的构造函数的范围内评估指定的。 [ 例子:

        class X {
          int a;
          int b;
          int i;
          int j;
        public:
          const int& r;
          X(int i): r(a), b(i), i(i), j(this->i) { }
        };
    

    初始化X::r引用X::a,用构造函数参数i的值初始化X::b用构造函数参数i的值初始化X::i ,并用X::i的值初始化X::j;每次创建 X 类的对象时都会发生这种情况。 —结束示例]
    [ 注意:因为 mem-initializer 是在构造函数的范围内计算的,所以 this 指针可以在 mem-initializer 的表达式列表中使用来引用正在初始化的对象。 ——尾注]

    【讨论】:

      【解决方案3】:

      由于以下几点,所有 C++ 编译器都遵循以下几点:

      1. 构造函数初始化列表只能与类构造函数一起存在
      2. 在初始化列表中只有相同的类成员和基类 可以调用构造函数
      3. 初始化的顺序与类数据成员的顺序相同 被声明

      当编译器将 if 视为初始化列表的一部分时,它会立即将其识别为类成员并且一切正常(第 2 点)。
      如果您尝试除if 之外的任何其他内容,编译器会报错。

      在您进行赋值的第二种情况下,编译器有 if 的 2 个候选者。它可以是类成员或局部变量。由于局部变量在最内部的范围内,编译器将i 视为i 而不是this-&gt;i

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-11-28
        • 1970-01-01
        • 2019-10-23
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多