0
#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?

4

3 回答 3

2

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

所以他们在这里。我增加了重点以突出关键陈述。

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

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

(§12.6.2/12) mem-initializer 的 expression-list 或 braced-init-list 中的名称在指定 mem-initializer的构造函数的范围内进行评估。[ 例子:

    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::aX::b用构造函数参数的值初始化,用构造函数参数的值i初始化X::iiX::j用 的值初始化X::i;每次创建 X 类的对象时都会发生这种情况。— end example ]
[ 注意:因为 mem-initializer 是在构造函数的范围内计算的,所以this可以在 mem-initializer 的表达式列表中使用指针来引用正在初始化的对象。——尾注]

于 2012-10-09T05:44:58.560 回答
1

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

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

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

在您进行分配的第二种情况下,编译器有 2 个候选者iand f。它可以是类成员或局部变量。由于局部变量在最内部的范围内,编译器认为iasi和 not this->i

于 2012-10-09T05:15:33.083 回答
0

编译器被设计为使用左手if作为类范围的成员和右手if作为构造函数范围的成员。

于 2012-10-09T05:15:31.827 回答