C ++: объявление параметра скрывает члена класса даже с ключевым словом this - PullRequest
5 голосов
/ 29 марта 2019

Я недавно начал использовать «Уровень предупреждения 4» и обрабатывать предупреждения как ошибки при кодировании в C ++.Я хотел бы получить более подробную информацию о следующем фрагменте:

struct Foo
{
    Foo(int size)
        //:size{ size } // <- More on this later.
    {
        this->size = size;
    }

    void func(int size)
    {
        this->size = size;
    }

    int size;
};

int main()
{
    Foo a{ 1 };
    a.func(2);
}

Итак, я получаю следующее предупреждение / ошибку из Visual Studio 2019:

Ошибка: C2220 - Предупреждение обрабатывается как ошибка - файл объекта не создан.

Предупреждение: C4458 - Объявление размера указывает член класса.

Предупреждение указывает, что size член скрыт параметром метода, который также называется size.Вывод указывает, что ошибка не из конструктора, а из метода func.Я нахожу это непонятным, так как конструктор, похоже, не имеет этой проблемы (действительно, удаление func позволяет компилировать фрагмент).

Понижение уровня предупреждения позволяет приложению компилироваться, и кажется, чтоработать как задумано.Использование списка инициализаторов вместо тела конструктора (см. Закомментированную строку) также, похоже, работает, но я предполагаю, что это связано с семантикой списка инициализаторов.

Я понимаю, что ошибка говорит о том, что имя параметра sizeиз func конфликтует с Foo членом с тем же именем, но разве ключевое слово this не должно устранить эту путаницу?Это просто слишком строгий компилятор Microsoft?

Ответы [ 2 ]

1 голос
/ 29 марта 2019

но не должно ли ключевое слово this устранить эту путаницу?

Дело не в том, что компилятор смущен тем, что this->size отличается от size. Скорее всего, вы получите предупреждение, даже если вы удалите эту строку. Компилятор предупреждает вас о том, что имя аргумента функции скрывает имя члена.

1 голос
/ 29 марта 2019

На этом уровне эти предупреждения касаются определения лучших практик. Обеспечение того, чтобы имена переменных-членов отличались от имен переменных параметров функции, является хорошей практикой, поскольку делает ваш код более читабельным. Хотя «this-> size» действительно устраняет неоднозначность, это также означает, что при поиске использования размера в этой функции вы должны проверить, на какую переменную вы ссылаетесь. Изменение имен устраняет неоднозначность через 2 месяца, когда вы исправляете ошибку :) Рекомендуемые исправления включают в себя либо изменение переменных-членов на префикс, такой как m_size, что также дает преимущество улучшения автозаполнения / intellisense, либо изменения имя параметра.

Замечу, что предупреждения как ошибки и W4 - это то, к чему я настоятельно рекомендую придерживаться. Хорошо, что вы позаботились о вашем коде:)

...