C++构造函数初始化列表的奇怪之处
在编写我的类时,我一直是一个好孩子,在所有成员变量前添加 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
I have always been a good boy when writing my classes, prefixing all member variables with 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
}
However, recently I forgot to do that and ended up writing:
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) {}
};
Believe it or not, the code compiled with no errors/warnings and the assignments took place correctly! It was only when doing the final check before checking in my code when I realised what I had done.
My question is: why did my code compile? Is something like that allowed in the C++ standard, or is it simply a case of the compiler being clever? In case you were wondering, I was using Visual Studio 2008
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
是的,这是有效的。在构造函数类的上下文中查找成员初始值设定项列表中的名称,以便
int1
找到成员变量的名称。在构造函数本身的上下文中查找初始值设定项表达式,以便 int1 找到屏蔽成员变量的参数。
Yes, it's valid. The names in the member initializer list are looked up in the context of the constructor's class so
int1
finds the name of member variable.The initializer expression is looked up in the context of the constructor itself so
int1
finds the parameter which masks the member variables.你所做的是标准的C++。初始化列表中只能初始化成员变量或基类,因此括号外的变量是明确的。在括号内,应用典型的作用域规则,并且成员被参数名称遮盖。
What you have done is standard C++. Only member variables or base classes may be initliazed in the initialization list, so the variable outside the paranthesis is unambiguous. Within the parenthesis, the typical scoping rules apply, and the members are overshadowed by the parameter names.
这是完全正常的行为。正如 AAT 正确指出的那样,不存在任何歧义。由列表初始化的变量必须是类成员。这是标准的,适用于所有兼容的编译器。
使用这样的列表时唯一要记住的是,不理解此类代码的人可能必须维护它。只要您知道自己在做什么,编写这样的初始化代码就没有什么问题。
This is perfectly normal behavior. As AAT rightly pointed out, there is no ambiguity. The variables initialised by the list have to be class members. This is standard and works across all compliant compilers.
The only thing to remember while using a list like this is that a person who doesn't understand this kind of code may have to maintain it. There is nothing wrong with writing initialisation code like this as long as you know what you are doing.
我想这是可行的,因为您在初始化列表中使用了 int1,并且您唯一可以初始化的是成员变量 =>事实上,哪个变量正在被初始化是明确的。
是否所有 C++ 编译器都如此宽容是另一回事!
I imagine this works because you were using int1 in the initialiser list, and the only things you can initialise are member variables => it was in fact unambiguous which variable was being initialised.
Whether all C++ compilers would be this forgiving is another matter!
你所做的一切都是正常的。这种实现甚至可以避免您使用“this”指针(在本例中)。
What you have done is normal. This kind of implementation avoids you from even using the 'this' pointer (in this case).