Является ли присвоение имен переменным после их типа плохой практикой? - PullRequest
14 голосов
/ 29 августа 2010

Я программирую на C ++, используя стиль именования подчеркивания (в отличие от случая с верблюдом), который также используется в STL и boost. Тем не менее, поскольку оба типа и переменные / функции имеют все имена в нижнем регистре, объявление переменной-члена следующим образом приведет к ошибкам компилятора (или, по крайней мере, к проблемам):

position position;

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

Position position;

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

В C довольно часто для этого используются загадочные однобуквенные переменные:

int i;

Но я нахожу это немного, ну, загадочным:

position p;

Существуют ли какие-либо практические правила для именования переменных, которые я могу использовать, чтобы избежать этого?

В моем коде есть и другие примеры, если вам нужно что-то для работы:

mouse_over(entity entity) // Returns true if the mouse is over the entity

manager &manager; // A reference to the framework's manager

audio audio; // The audio subsystem

Edit:

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

Например, вводить пользовательские типы нестандартной библиотеки с прописной буквы и начинать нетипизмы со строчной буквы

Это будет соответствовать STL и boost, так что я мог бы использовать это. Однако большинство из вас согласны с тем, что следует избегать такого именования, независимо от того, компилируется оно или нет. Как и Страуструп:

неразумно выбирать имена, которые отличаются только заглавными буквами.

Ответы [ 10 ]

10 голосов
/ 29 августа 2010

Локальное значение редко является хорошим уникальным глобальным описанием типа:

cartesian_point_2d position;  // rectangular, not polar coordinates
mouse_over(ui_entity entity); // not a business layer entity
xyz_manager& manager;         // what's a manager without something to manage?
audio_system audio;
8 голосов
/ 29 августа 2010

Назначение переменной с тем же именем, что и у ее типа, почти всегда является плохой идеей, поскольку очень трудно определить, какой код относится к типу, а какой код относится к переменной.Например, рассмотрим следующий класс:

struct position
{
    void operator()() { }
};

// later on, somewhere:
position position;

Теперь, если мы увидим строку кода, которая использует:

position()

, мы не можем с готовностью сказать, создает ли это position объект или звонки position::operator()().Мы должны вернуться и посмотреть, существует ли в настоящее время объект с именем position.

Соглашения об именах - очень обидчивая, субъективная и спорная вещь.Я бы просто рекомендовал выбрать тот, который каким-то образом отличает типы от переменных.Лично я выбираю использование заглавных букв в моих типах и оставляю переменные, начинающиеся со строчной буквы

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

3 голосов
/ 29 августа 2010

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

То, что может понадобиться встроить в имя переменной, это семантическое значение переменной . Как "ширина", "длина", "индекс", "координата", "прямоугольник", "цвет", "строка", "конвертер" и так далее. К сожалению, многие люди, когда они это видят, ошибочно полагают, что эти части имен предназначены для описания типа переменной. Это недоразумение часто заставляет их впутываться в эту дурную практику (именовать переменные после их типов) позже в своем коде.

Классическим известным примером такого недоразумения является так называемая Венгерская запись . Венгерская нотация предполагает префикс имен переменных со специальными унифицированными префиксами, которые описывают семантику переменной. В этой оригинальной форме венгерская нотация является чрезвычайно полезным соглашением об именах. Однако во многих практических случаях он искажается во что-то совершенно иное: перед именами переменных ставится то, что описывает их тип . Последнее, конечно, не очень хорошая идея.

2 голосов
/ 29 августа 2010

Лично я пишу названия классов с большой буквы.

Я не согласен с тем, что "неразумно выбирать имена, которые отличаются только заглавными буквами", в данном конкретном случае. Неразумно выбирать имена, которые до смешного похожи. PoSItIoN и PoSiTIoN до смешного похожи. Position и position нет. Просто убедитесь, что при поиске кода вы знаете и можете контролировать, чувствительны ли вы к этому регистру или нечувствительны.

В тех случаях, когда у меня есть функция, которая использует только одну переменную определенного типа, я вполне могу назвать ее после типа, поскольку в английском языке, если что-то было «единственной позицией, о которой мы говорим», мы Я бы назвал это «позицией». Следовательно, имя переменной может быть разумно position.

В противном случае в ваших примерах я мог бы пойти с:

position pos;  // pretty sure people will realise I don't mean "positron".

mouse_over(entity target) // Returns true if the mouse is over the entity

manager &fmanager; // A reference to the framework's manager

devices::audio audio; // The audio subsystem
audio self; // "this" audio subsystem
audio audio_out; // The audio subsystem I'm configured to use for output

В последнем примере предполагается, что эти проблемы могут быть решены с помощью пространств имен - за пределами пространства имен, в котором определен audio, вы можете смело ссылаться на него как audio. Внутри этого пространства имен функции, работающие в аудиоподсистеме, часто являются частями интерфейса класса audio, которые просто являются свободными функциями (в этом случае используются соглашения, такие как self, other, lhs, rhs ), или же это какое-то многоуровневое устройство или система, в которой звуковая подсистема является зависимостью (в каком случае зависимость для какой цели?).

Кстати,

entity и manager - ужасные имена для классов, поскольку ни один из них не говорит вам ничего о том, что представляет класс. Каждая отдельная вещь является «сущностью», и хотя не все управляет чем-то другим, «управлять» безнадежно расплывчато.

2 голосов
/ 29 августа 2010

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

1 голос
/ 29 августа 2010

У меня та же самая "проблема" на регулярной основе.Я думаю, что это проблема абстракции: в случае с Position я бы предложил немного абстрагироваться и ввести тип Point или что-то в этом роде.Или укажите, какую позицию занимает:

position mouse_pointer_pos;
1 голос
/ 29 августа 2010

Вот почему я выбрал старую практику MFC, заключающуюся в добавлении префиксов-членов к m_, как в «m_position». Многие Java-люди делали «thePosition» по той же самой причине, хотя, если бы вы указали на сходство в то время, они стали бы смешными и раздражительными.

0 голосов
/ 01 июня 2019

Нет, я делаю это время от времени, и это не вызывает проблем в мире Microsoft.Например,

class compiler
{
    symbol_table symbol_table;
};

никогда не вызывало путаницы.Кстати, я назвал свою кошку «кошкой», и это тоже не вызвало путаницы.

0 голосов
/ 29 августа 2010

Вы можете просто следовать существующим правилам, например, Руководство по стилю Google C ++

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

Я экспериментировал с венгерским и мне не понравилось, большинство хороших программистов я знаю, не используйте его.

Главное, что я хотел бы сделать - это делает код менее читабельным.

0 голосов
/ 29 августа 2010

Короткий и полу неправильный ответ: если у вас достаточно переменных, с которыми вы работаете в одном месте, и вам нужны нешифрованные имена переменных, возможно, у вас слишком много переменных.

Хотя я на самом деле не согласен с этим, в некоторой степени. Я думаю, что в этом есть доля правды, но только это.

Некоторые короткие имена переменных в C ++ являются просто традиционными, и люди знают, что они имеют в виду, потому что они программировали на C / C ++ некоторое время. Использование i для индексной переменной является примером.

Я думаю, что имена переменных должны быть названы в соответствии с их назначением. Какова позиция? Чем руководит менеджер? Почему этот конкретный экземпляр аудиоподсистемы должен существовать?

Конечная нотация _ используется для различения имен переменных-членов. Это может быть очень полезно, когда кто-то начинает упоминать x из ниоткуда, чтобы увидеть x_ и знать, что он исходит из класса и не объявлен во внешней или глобальной области действия.

...