This-> ссылаться на все
Недавно я провел много времени с javascript, и теперь я возвращаюсь на С++. Когда я получаю доступ к члену класса из метода, я кормлю его, чтобы префикс его с помощью this->
.
class Foo {
int _bar;
public:
/* ... */
void setBar(int bar) {
this->_bar = bar;
// as opposed to
_bar = bar;
}
}
При чтении это спасает меня мозговым циклом, пытаясь понять, откуда он.
Есть ли причины, по которым я не должен этого делать?
Ответы
Ответ 1
Использование this- > для переменных класса вполне приемлемо.
Однако не начинайте идентификаторы с подчеркивания или не включайте в себя любые идентификаторы с двойным подчеркиванием __
. Есть несколько классов зарезервированных символов, которые легко ударить, если вы нарушите одно из этих двух правил. (В частности, _IdentifierStartingWithACapital зарезервирован стандартом для компиляторов).
Ответ 2
В принципе, доступ к элементам через this->
- это стиль кодирования, который может помочь в создании понятности, но, похоже, это вопрос вкуса.
Однако вы также используете префиксные элементы с _
(подчеркивание). Я бы сказал, что это слишком много, вы должны пойти на любой из двух стилей.
Ответ 3
Есть ли причины, по которым я не должен этого делать?
Да, есть причина, почему вы не должны этого делать.
Ссылка на переменную-член с помощью this->
строго требуется только при скрытии имени, например:
class Foo
{
public:
void bang(int val);
int val;
};
void Foo::bang(int val)
{
val = val;
}
int main()
{
Foo foo;
foo.val = 42;
foo.bang(84);
cout << foo.val;
}
Выход этой программы 42
, а не 84
, потому что в bang
переменная-член была скрыта, а val = val
приводит к отсутствию-op. В этом случае требуется this->
:
void Foo::bang(int val)
{
this->val = val;
}
В других случаях использование this->
не имеет никакого эффекта, поэтому оно не требуется.
Это само по себе не является основанием не использовать this->
. Однако сохранение такой программы является основанием для использования this->
.
Вы используете this->
в качестве средства документации, чтобы указать, что подлежащая замене является переменной-членом. Однако для большинства программистов это не то, что usign this->
действительно документирует. Использование this->
документов:
Здесь есть скрытое имя, поэтому я использую специальный техника, чтобы обойти это.
Поскольку это не то, что вы хотели передать, ваша документация нарушена.
Вместо использования this->
для документирования того, что имя является переменной-членом, используйте схему рационального именования последовательно, где переменные-члены и параметры метода никогда не могут быть одинаковыми.
Изменить Рассмотрим еще одну иллюстрацию той же идеи.
Предположим, что в моей кодовой базе вы нашли это:
int main()
{
int(*fn)(int) = pingpong;
(fn)(42);
}
Довольно необычная конструкция, но, будучи опытным программистом на С++, вы видите, что происходит здесь. fn
является указателем на функцию и присваивается значение pingpong
, что бы это ни было. И тогда функция, на которую указывает pingpong
, вызывается с значением singe int
42
. Поэтому, удивляясь, почему в мире вам нужна такая штуковина, вы ищите pingpong
и находите это:
static int(*pingpong)(int) = bangbang;
Хорошо, так что bangbang
?
int bangbang(int val)
{
cout << val;
return val+1;
}
"Теперь, подождите секунду. Что в мире происходит здесь? Почему нам нужно создать указатель на функцию, а затем вызвать это? Почему бы просто не вызвать функцию? Разве это не то же самое?"
int main()
{
bangbang(42);
}
Да, это то же самое. Наблюдаемые эффекты одинаковы.
Удивляясь, действительно ли это все это, вы видите:
/* IMPLEMENTATION NOTE
*
* I use pointers-to-function to call free functions
* to document the difference between free functions
* and member functions.
*/
Таким образом, единственная причина, по которой мы используем указатель на функцию, - показать, что вызываемая функция является свободной функцией
и не является функцией-членом.
Это похоже на "вопрос стиля" для вас? Потому что мне кажется безумием.
Ответ 4
Здесь вы найдете:
Если имя члена класса не скрыто, использование имени члена класса эквивалентно использованию имени члена класса с этим указателем и оператором доступа к члену класса (- > ).
Ответ 5
Я думаю, вы делаете это назад. Вы хотите, чтобы код заверил вас, что происходит именно то, что ожидается.
Зачем добавлять дополнительный код, чтобы указать, что ничего особенного не происходит? Доступ к членам класса в функциях-членах происходит все время. Это было бы ожидаемо. Было бы намного лучше добавить дополнительную информацию, если это не обычные вещи, которые происходят.
В коде, подобном этому
class Foo
{
public:
void setBar(int NewBar)
{ Bar = NewBar; }
вы спрашиваете себя: "Откуда мог бы Bar
?".
Как это задатчик в классе, что бы он установил, если бы не переменная класса класса?! Если бы это было не так, тогда было бы повод добавить много информации о том, что на самом деле происходит здесь!
Ответ 6
Поскольку вы уже используете соглашение, чтобы обозначить, что идентификатор является членом данных (хотя это не тот, который я бы рекомендовал), добавление this->
просто избыточно почти во всех случаях.
Ответ 7
Это несколько субъективный вопрос. this->
выглядит гораздо более python-идиоматичным, чем С++ - идиоматическим. В С++ существует только несколько случаев, когда требуется this->
, относящаяся к именам в родительских классах шаблонов. В целом, если ваш код хорошо организован, для читателя будет очевидно, что он должен быть членом или локальной переменной (глобальные переменные следует избегать), а сокращение количества, которое нужно читать, может уменьшить сложность. Кроме того, вы можете использовать необязательный стиль (мне нравится trailing _
), чтобы указать переменные-члены.
Ответ 8
На самом деле это ничего не наносит вреда, но программисты, опытные с OO, увидят его и посчитают это странным. Аналогично удивительно видеть "условные обозначения йоды", т.е. if (0 == x)
.