2010-08-28 5 views
11

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

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:

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

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

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

Неразумно выбирать имена, отличающиеся только капитализацией.

+1

Имена типов начинаются с верхнего регистра. Имена переменных начинаются с нижнего регистра. И имена переменных никогда не бывают короткими.Попробуйте найти источник для всех экземпляров переменной 'i'. –

+0

В коде есть глава об именах переменных. –

+0

'i' отлично подходит для имени индексной переменной или итератора, который является локальным для строки 3-4 для цикла. Определенно не рекомендуется для переменных-членов. –

ответ

7

Местный смысл редко бывает хорошим уникальное глобальное описание типа:

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; 
+2

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

+0

Из опыта, но это не значит, что вы не можете применить шаблоны. Во-первых, обратите внимание, что в каждом случае я изменил имя типа. Это потому, что переменная имеет контекст, более похожий на тип. Другой способ добавить контекст с типами - это пространство имен. Затем я попытался придумать другое приложение, в котором можно использовать одно и то же слово, но тип не может быть, и добавил некоторую отличительную характеристику имени типа. Например, метеорологические спутники также имеют положение, которое может быть (широта, долгота, высота). –

+0

Обратите внимание, что я все еще недоволен 'audio_system', я выбрал это, потому что это ваш собственный комментарий об этом, но я бы предпочел что-то вроде' pcm_audio_player' или 'midi_audio_processor' или' wavfile_audio_recorder', которое сообщает, какой тип аудио и независимо от того, записывает ли он, воспроизводит или изменяет аудиопоток. –

2

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

8

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

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

// later on, somewhere: 
position position; 

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

position() 

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

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

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

1

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

3

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

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

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

+1

+1: Я ненавижу венгерскую нотацию и всю бессмысленность 'm_'. –

+2

@ Джон: если вы ненавидите венгерскую нотацию, зачем давать +1 ответ, который восхваляет венгерскую нотацию? ;-) –

-1

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

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

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

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

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

+0

IMO, короткие, загадочные имена подходят для локальных переменных и параметров. Но переменные-члены? Я не уверен, что это не смущает. – Noarth

+0

@Noarth - И, судя по всему, мой ответ был путаным. Ну что ж. :-) – Omnifarious

+0

Downvote для предоставления ответа, который вы признаете ошибочным и запутанным. –

1

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

position mouse_pointer_pos; 
0

Вы можете просто следовать существующим правилам, например. Google's C++ style guide

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

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

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

+3

Руководство по стилю Google ужасно для современного кода на C++. – GManNickG

2

Лично я использую имена классов.

Я не согласен с тем, что «это неразумно выбирать имена, которые отличаются только капитализацией», в этом конкретном случае. Неразумно выбирать имена, которые сбивчиво похожи. PoSItIoN и PoSiTIoN смутно похожи. Position и 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 определен, вы можете безопасно см. его audio. Внутри этого пространства имен функции, работающие на аудиоподсистеме, часто либо являются частями интерфейса класса audio, которые просто являются бесплатными функциями (в этом случае используются условные обозначения, такие как self, other, lhs, rhs), или же это своего рода многоуровневое устройство или системы, которые имеют аудиоподсистему как зависимость (в этом случае, зависимость для какой цели?).

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

Смежные вопросы