Инициализация Конструктора 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

11
задан Trevor Hickey 20 January 2016 в 08:53
поделиться

5 ответов

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

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

26
ответ дан 3 December 2019 в 01:15
поделиться

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

Другой вопрос, будут ли все компиляторы C ++ такими снисходительными!

0
ответ дан 3 December 2019 в 01:15
поделиться

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

0
ответ дан 3 December 2019 в 01:15
поделиться

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

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

2
ответ дан 3 December 2019 в 01:15
поделиться

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

15
ответ дан 3 December 2019 в 01:15
поделиться
Другие вопросы по тегам:

Похожие вопросы: