Я программирую на C ++, используя стиль именования подчеркивания (в отличие от верблюжьего), который также используется в STL и boost. Тем не мение, поскольку оба типа и переменные / функции имеют все имена в нижнем регистре, объявление переменной-члена следующим образом приведет к ошибкам компилятора (или, по крайней мере, к проблемам):
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
Редактировать:
Мне было любопытно увидеть если сам Бьярне Страуструп есть что сказать по этому вопросу. Очевидно, что нет, но он предлагает соглашения по кодированию, которые обойдут мои проблемы с компилятором:
Например, пишите прописные буквы нестандартных библиотек с прописной буквы и начинайте с нетипичных букв
, что будет соответствовать STL и повысить, так что я мог бы использовать это. Однако большинство из вас согласны с тем, что следует избегать такого именования, независимо от того, компилируется оно или нет. Как и Страуструп:
неразумно выбирать имена, отличающиеся только заглавными буквами.
Локальное значение редко является хорошим уникальным глобальным описанием типа:
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;
Лично я пишу имена классов с большой буквы.
Я не согласен с тем, что «неразумно выбирать имена, которые отличаются только заглавными буквами» в данном конкретном случае. Неразумно выбирать имена, сходные до степени смешения. POSITIO
и POSITION
похожи до степени смешения. Позиция
и позиция
не являются. Просто убедитесь, что при поиске кода вы знаете и можете контролировать, делаете ли вы это с учетом регистра или без учета.
В тех случаях, когда у меня есть функция, которая использует только одну переменную определенного типа, я вполне мог бы назвать ее в честь типа, поскольку в английском языке, если что-то было, «единственная позиция, о которой мы говорим», мы d ссылаться на это как на «положение». Следовательно, имя переменной вполне может быть 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
, которые просто являются свободными функциями (в этом случае используйте такие соглашения, как self
, other
, lhs
, rhs
), или еще какие-то многоуровневые устройства или системы, которые имеют аудиоподсистему в качестве зависимости (в этом случае зависимость для какой цели? ).Между прочим,
entity
и manager
— ужасные имена для классов, поскольку ни одно из них ничего не говорит вам о том, что представляет собой класс. Каждая дискретная вещь — это «сущность», и хотя не все управляет чем-то другим, «управлять» безнадежно расплывчато.
Вот почему я перенял старую практику MFC, предваряя переменные-члены префиксом m_, как в "m_position". Многие Java-люди сделали бы "thePosition" по сути по той же причине, хотя, если бы вы указали на сходство в то время, они стали бы смешными и разглагольствовали на вас.
Вы можете просто следовать существующим рекомендациям, например. Руководство по стилю C++ от Google
Полезно знать, что именование является важной проблемой, но по моему опыту слишком много думать об этом так же вредно, как и не знать об этом.
Я экспериментировал с венгерским, и он мне не понравился. знайте, не используйте его.
Главное, что я хотел бы отметить, это делает код менее читаемым.
Давать переменной то же имя, что и ее тип, почти всегда плохая идея, потому что очень трудно сказать, какой код относится к типу, а какой код относится к переменной. Например, рассмотрим следующий класс:
struct position
{
void operator()() { }
};
// later on, somewhere:
position position;
Теперь, если мы видим строку кода, которая использует:
position()
мы не можем сразу сказать, создает ли она объект position
или вызывает position ::оператор()()
. Мы должны вернуться и посмотреть, есть ли объект с именем position
в настоящее время в области видимости.
Соглашения об именах — очень щекотливая, субъективная и дискуссионная вещь. Я бы просто рекомендовал выбрать тот, который каким-то образом отличает типы от переменных. Лично я предпочитаю использовать заглавные буквы для своих типов и оставлять переменные, начинающиеся со строчной буквы.
На самом деле не имеет значения, как вы их различаете (ваши предложения использовать заглавные буквы или нижнее подчеркивание в конце являются общими), лишь бы ваше использование было последовательным.
У меня регулярно возникает одна и та же "проблема". Я думаю, что это проблема абстракции: в случае с Position я бы предложил немного больше абстрагироваться и ввести тип Point или что-то в этом роде. Или укажите, какая позиция указана:
position mouse_pointer_pos;
Да, это плохая практика. Имена переменных должны быть более конкретными, если они имеют длительный срок службы или важное значение (временные имена в порядке). Помните, что C++ очень строго типизирован — у вас не может быть переменной, и вы не можете быть уверены, какой у нее тип. Например, переменный тип Type просто означает, что у него нет имени.
Короткий и почти неверный ответ: если у вас есть достаточно переменных, с которыми вы работаете в одном месте, и вам нужны незашифрованные имена переменных, возможно, у вас слишком много переменных.
Хотя я на самом деле не согласен с этим, в некоторой степени. Я думаю, что в этом есть доля правды, но только в этом.
Некоторые короткие имена переменных в C++ просто традиционны, и люди знают, что они означают, потому что некоторое время программировали на C/C++. Примером может служить использование i
для индексной переменной.
Я думаю, что имена переменных должны быть названы в соответствии с их назначением. Какова позиция? Чем управляет менеджер? Почему должен существовать этот конкретный экземпляр звуковой подсистемы?
Конечная нотация _
используется для различения имен переменных-членов. Это может быть очень полезно, когда кто-то начинает упоминать x
из ниоткуда, чтобы увидеть x_
и знать, что это происходит из класса, а не объявлено во внешней или глобальной области видимости. .
Именование переменных в соответствии с их типом действительно является плохой практикой. Код должен быть максимально типонезависимым. Это означает, что любые ссылки на фактические типы должны быть ограничены объявлениями (опять же, насколько это возможно). Попытка встроить информацию о типе в имя переменной нарушит этот принцип. Не делай этого.
В имя переменной можно встроить ее семантическое значение. Например, «ширина», «длина», «индекс», «координата», «прямоугольник», «цвет», «строка», «конвертер» и так далее. К сожалению, многие люди, увидев это, ошибочно предполагают, что эти части имен предназначены для описания типа переменной. Это непонимание часто заставляет их прибегать к этой плохой практике (называть переменные в соответствии с их типами) позже в своем коде.
Классическим хорошо известным примером такого непонимания является так называемая венгерская нотация. Венгерская нотация подразумевает предварение имен переменных специальными унифицированными префиксами, описывающими семантику переменной. В этой исходной форме венгерская нотация является чрезвычайно полезным соглашением об именах. Однако во многих практических случаях это искажается и превращается во что-то совершенно другое: к именам переменных добавляется префикс, описывающий их тип. Последнее, конечно, не лучшая идея.