Странность списка инициализации С++ Constructor
Я всегда был хорошим мальчиком при написании своих классов, префикс всех переменных-членов с помощью 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) {}
};
Верьте или нет, код, составленный без ошибок/предупреждений и назначений, прошел правильно! Это было только при выполнении окончательной проверки, прежде чем проверять мой код, когда я понял, что сделал.
Мой вопрос: почему мой код скомпилировался? Что-то вроде этого разрешено в стандарте С++, или это просто случай, когда компилятор умный? Если вам интересно, я использовал Visual Studio 2008
Ответы
Ответ 1
Да, это действительно. Имена в списке инициализаторов членов просматриваются в контексте класса конструктора, поэтому int1
находит имя переменной-члена.
Инициализационное выражение просматривается в контексте самого конструктора, поэтому int1
находит параметр, который маскирует переменные-члены.
Ответ 2
Что вы сделали, это стандартный С++. В списке инициализации могут быть инициализированы только переменные-члены или базовые классы, поэтому переменная, находящаяся за пределами paranthesis, недвусмысленна. В круглых скобках применяются типичные правила определения области видимости, а элементы затенены именами параметров.
Ответ 3
Это совершенно нормальное поведение. Как справедливо указал ААТ, нет никакой двусмысленности. Переменные, инициализированные списком, должны быть членами класса. Это стандартно и работает во всех совместимых компиляторах.
Единственное, что следует помнить при использовании такого списка, это то, что человеку, который не понимает этот тип кода, возможно, придется его поддерживать. Нет ничего плохого в написании кода инициализации, как это, если вы знаете, что делаете.
Ответ 4
Я предполагаю, что это работает, потому что вы использовали int1 в списке инициализации, и единственное, что вы можете инициализировать, это переменные-члены = > это было фактически однозначно, какая переменная инициализировалась.
Будут ли все компиляторы С++ этим прощающим - это другое дело!
Ответ 5
То, что вы сделали, является нормальным. Такая реализация позволяет избежать использования даже указателя 'this' (в данном случае).