Подтвердить что ты не робот

Странность списка инициализации С++ 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

4b9b3361

Ответ 1

Да, это действительно. Имена в списке инициализаторов членов просматриваются в контексте класса конструктора, поэтому int1 находит имя переменной-члена.

Инициализационное выражение просматривается в контексте самого конструктора, поэтому int1 находит параметр, который маскирует переменные-члены.

Ответ 2

Что вы сделали, это стандартный С++. В списке инициализации могут быть инициализированы только переменные-члены или базовые классы, поэтому переменная, находящаяся за пределами paranthesis, недвусмысленна. В круглых скобках применяются типичные правила определения области видимости, а элементы затенены именами параметров.

Ответ 3

Это совершенно нормальное поведение. Как справедливо указал ААТ, нет никакой двусмысленности. Переменные, инициализированные списком, должны быть членами класса. Это стандартно и работает во всех совместимых компиляторах.

Единственное, что следует помнить при использовании такого списка, это то, что человеку, который не понимает этот тип кода, возможно, придется его поддерживать. Нет ничего плохого в написании кода инициализации, как это, если вы знаете, что делаете.

Ответ 4

Я предполагаю, что это работает, потому что вы использовали int1 в списке инициализации, и единственное, что вы можете инициализировать, это переменные-члены = > это было фактически однозначно, какая переменная инициализировалась.

Будут ли все компиляторы С++ этим прощающим - это другое дело!

Ответ 5

То, что вы сделали, является нормальным. Такая реализация позволяет избежать использования даже указателя 'this' (в данном случае).