C ++构造函数初始化列表奇怪

时间:2010-03-19 10:12:53

标签: c++ constructor initialization-list

在编写我的类时,我一直都是个好孩子,在所有成员变量前加上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

5 个答案:

答案 0 :(得分:26)

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

初始化表达式在构造函数本身的上下文中查找,因此int1找到掩盖成员变量的参数。

答案 1 :(得分:15)

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

答案 2 :(得分:2)

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

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

答案 3 :(得分:0)

我认为这是有效的,因为您在初始化列表中使用了int1,并且您可以初始化的唯一内容是成员变量=>事实上,这个变量正在被初始化是明确无误的。

是否所有C ++编译器都是宽容的另一个问题!

答案 4 :(得分:0)

你做的是正常的。这种实现避免了你甚至使用'this'指针(在这种情况下)。