Должен ли я использовать одно и то же имя для переменной-члена и параметр функции в С++

Мне интересно, полезно ли использовать одно и то же имя как для переменной-члена, так и для параметра функции в С++. Я исхожу из фона Java, где это было распространено. Мне интересно, есть ли в С++ недостатки, выполняющие следующее (работает код):

class Player
{
    public:
    void setState(PlayerState *state)
    {
        this->state = state;
    }

    private:
       PlayerState *state;
}

Спасибо за ответы. Насколько я понимаю, в то время как это работает, лучшей практикой было бы поставить какой-то маркер для дифференциации переменной-члена из параметров функции, например:

 _ or m_

В некоторых редакторах (например, Qt Designer) переменные-члены отображаются в разных цветах. Вот почему не было необходимости добавлять какие-либо префиксы.

Ответы

Ответ 1

Это правильно и разрешено Стандартом. Но лучший подход - использовать некоторые соглашения об именах для переменных-членов. Например, вы можете использовать префикс m_ для всех переменных-членов, тогда любой может сделать вывод, что m_state. Это повышает читаемость кода и позволяет избежать распространенных ошибок.

Кроме того, если m_state является членом, тогда вам не нужно писать this->m_state = state в функции-члене, вы можете просто написать m_state = state. В вашем текущем коде нужна часть this->, без которой state = state станет самоопределением.

Ответ 2

Обычно люди просто добавляют символ подчеркивания после переменной или используют более короткие описательные имена переменных для параметра функции.

Мне лично не нравится одно и то же имя, потому что, читая его, легко ошибаться.

Ответ 3

На самом деле нет никакой разницы между С++ и java, единственным недостатком является то, что вы должны ввести this- > state = state вместо state = arg. Но ваш код вполне приемлем, он больше напоминает стиль, чем что-либо еще.

Ответ 4

Обратите внимание, что некоторые компиляторы (vs 2015) могут генерировать предупреждение, если переменная затеняет другую. Конечно, можно отключить подобные предупреждения. Но я считаю, что это хорошая практика, чтобы эти проверки были включены.

Ответ 5

Я предлагаю вам следовать некоторому соглашению стиля кодирования. Лично я использую:

class Player
{
    public:
    void setState(PlayerState *state)
    {
        _state = state;
    }

    private:
       PlayerState* _state;
}

Ответ 6

Это нормально, на самом деле это может быть даже хорошая форма, если только это будет в вашем конструкторе.

Ответ 7

Сделайте это так:

class Player
{
    public:
    void setState(PlayerState *state)
    {
        this->m_state = state;
    }

    private:
       PlayerState *m_state;
}

Вы поблагодарите меня через некоторое время. Ха-ха.. (:

Префикс "m_" ( "Member" ) отличает участников от функций и других вещей. Очень полезно с такими вещами, как intellisense (или любое другое автоматическое предложение IDE).

Кроме того, отметьте m_state как const, если вы не собираетесь менять его позже. На всякий случай.

Ответ 8

Это больше проблема стиля, чем что-либо еще. Большую часть времени, нет проблемы: state - очень плохое имя для переменной или значения, поскольку переменные и значения должны быть квалифицированными существительными, например:

void setState( PlayerState* newState )
{
    currentState = newState;
}

В теории, во всяком случае. На практике я нашел полезным использовать префиксы, вдоль линий:

class Player
{
    PlayerState* myState;
public:
    void setState( PlayerState* newState )
    {
        myState = newState;
    }
};

При чтении кода, если имя начинается с my, это явно член переменной (и если она начинается с our, это статический член переменная).

Обратите внимание, что в конструкторе вы можете делать такие вещи, как:

Player::Player( PlayerState* state )
    : state( state )
{
}

Я не уверен, что это делает для удобства чтения:

Player::Player( PlayerState* initialState )
    : myState( initialState )
{
}

выглядит намного понятнее (но для простых держателей данных это различие может не так важно).

Ответ 9

Я считаю хорошим выбором предоставить переменные-члены с тем же именем, что и параметры инициализации конструктора. Вот мои причины:

  • уменьшает количество идентификаторов = уменьшает сложность
  • вам не нужно изобретать столько идентификаторов
  • То же самое должно иметь одно и то же имя, если это возможно, то есть логически говоря, я знаю параметр!= член.
    • контексты и индексы позволяют присвоить одно и то же имя одной и той же вещи
  • вам легче найти ссылки (идентификаторы) на логическую вещь путем поиска, если все ссылки имеют одно и то же имя