11

在编写类时,我一直是个好孩子,所有成员变量都以 m_ 为前缀:

class Test {
    int m_int1;
    int m_int2;
public:
    Test(int int1, int int2) : m_int1(int1), m_int2(int2) {}
};

int main() {
    Test t(10, 20); // Just an example
}

然而,最近我忘了这样做,最后写了:

class Test {
    int int1;
    int int2;
public:
    // Very questionable, but of course I meant to assign ::int1 to this->int1!
    Test(int int1, int int2) : int1(int1), int2(int2) {}
};

信不信由你,编译的代码没有错误/警告,并且分配正确进行!只有在签入代码之前进行最后检查时,我才意识到自己做了什么。

我的问题是:为什么我的代码会编译?C++ 标准中是否允许这样的事情,还是仅仅是编译器聪明的一个例子?如果您想知道,我使用的是 Visual Studio 2008

4

5 回答 5

26

是的,它是有效的。在构造函数类的上下文中查找成员初始化器列表中int1的名称,从而找到成员变量的名称。

在构造函数本身的上下文中查找初始值设定项表达式,从而int1找到掩蔽成员变量的参数。

于 2010-03-19T10:21:22.880 回答
15

您所做的是标准 C++。初始化列表中只能初始化成员变量或基类,因此括号外的变量是明确的。在括号内,应用了典型的范围规则,并且成员被参数名称所掩盖。

于 2010-03-19T10:20:44.030 回答
2

这是完全正常的行为。正如 AAT 正确指出的那样,没有歧义。列表初始化的变量必须是类成员。这是标准的,适用于所有兼容的编译器。

使用这样的列表时唯一要记住的是,不理解这种代码的人可能必须维护它。只要您知道自己在做什么,编写这样的初始化代码就没有错。

于 2010-03-19T10:22:06.217 回答
0

我想这是可行的,因为您在初始化器列表中使用了 int1,而您唯一可以初始化的是成员变量 => 实际上,正在初始化哪个变量是明确的。

是否所有 C++ 编译器都会如此宽容是另一回事!

于 2010-03-19T10:15:40.407 回答
0

你所做的很正常。这种实现避免了您甚至使用“this”指针(在这种情况下)。

于 2010-03-19T20:18:05.183 回答