Соглашение об именах - подчеркивание в переменных C ++ и C # - PullRequest
123 голосов
/ 29 июня 2010

Обычно имя переменной _var отображается в поле класса. Что означает подчеркивание? Есть ли ссылка на все эти специальные соглашения об именах?

Ответы [ 18 ]

102 голосов
/ 29 июня 2010

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

В C ++ подчеркивание обычно указывает на закрытую переменную-член.

В C # я обычно вижу, что он используется только при определении базовой закрытой переменной-члена для открытого свойства. Другие закрытые переменные-члены не будут иметь подчеркивания. Это использование в значительной степени ушло на второй план с появлением автоматических свойств.

До:

private string _name;
public string Name
{
    get { return this._name; }
    set { this._name = value; }
}

После того, как:

public string Name { get; set; }
62 голосов
/ 10 декабря 2013

Пожалуйста, НЕ используйте UNDERSCORES перед тем, как любое имя переменной или имя параметра в C ++ !!!

Имена, начинающиеся с подчеркивания или двойного подчеркивания, ЗАБРОНИРОВАНЫ для реализаторов C ++.Имена с подчеркиванием зарезервированы для работы библиотеки.

Если у вас есть чтение в стандарте кодирования C ++, вы увидите, что на самой первой странице написано:

«Не переусердствуйте в присвоении имен, но используйте последовательное соглашение об именах: есть только два обязательных элемента: a) никогда не используйте« скрытые имена », начинающиеся с подчеркивания или содержащие двойное подчеркивание;(p2, Стандарты кодирования C ++, Херб Саттер и Андрей Александреску)

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

Попробуйтекомпилируя простую программу helloWorld.cpp, например:

g++ -E helloWorld.cpp

. Вы увидите все, что происходит в фоновом режиме.Вот фрагмент кода:

   ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
   try
     {
       __streambuf_type* __sb = this->rdbuf();
       if (__sb)
  {
    if (__sb->pubsync() == -1)
      __err |= ios_base::badbit;
    else
      __ret = 0;
  }

Вы можете увидеть, сколько имен начинаются с двойного подчеркивания!

Также, если вы посмотрите на виртуальные функции-члены, вы увидите, что * _vptr - сгенерированный указательдля виртуальной таблицы, которая автоматически создается, когда вы используете одну или несколько виртуальных функций-членов в вашем классе!Но это уже другая история ...

Если вы используете подчеркивание, у вас могут возникнуть конфликтные ситуации, и вы НЕ БУДЕТЕ ИДЕИ, что их вызывает, пока не станет слишком поздно.

41 голосов
/ 29 июня 2010

На самом деле соглашение _var исходит от VB, а не C # или C ++ (m _, ... это другое дело).

Это пришло для преодоления нечувствительности к регистру VB при объявлении Приоритизмов

например, такой код невозможен в VB, потому что он рассматривает user и User как один и тот же идентификатор

Private user As String

Public Property User As String
  Get
    Return user
  End Get
  Set(ByVal Value As String)
    user = value
  End Set
End Property

Таким образом, чтобы преодолеть это, некоторые использовали соглашение, чтобы добавить '_' в приватное поле, чтобы появилось вот так

Private _user As String

Public Property User As String
  Get
    Return _user
  End Get
  Set(ByVal Value As String)
    _user = value
  End Set
End Property

Поскольку многие соглашения предназначены для .Net и для сохранения некоторого единообразия между соглашениями C # и VB.NET, они используют один и тот же.

Я нашел ссылку на то, что я говорил: http://10rem.net/articles/net-naming-conventions-and-programming-standards---best-practices

Чехол для верблюда с ведущим символом подчеркивания. В VB.NET, всегда указывайте «Защищено» или «Приват», не используйте «Дим». Использование «М_» не рекомендуется, так как использование имя переменной, которая отличается от собственность только на случай, особенно с защищенные переменные как то нарушают соблюдение, и сделает вашу жизнь боль, если вы программируете в VB.NET, как вы придется назвать ваших членов что-то отличное от свойства аксессора / мутатора. Из всех предметы здесь, ведущие подчеркивание действительно единственный спорный. Я лично предпочитаю это прямо подчеркнутый случай верблюда для моего частные переменные, так что у меня нет квалифицировать имена переменных с помощью «this». отличить от параметров в конструкторы или в другом месте, где я скорее всего, будет конфликт имен. С учетом регистра VB.NET это еще важнее, как ваш свойства аксессора обычно имеют то же имя, что и ваш личный участник переменные за исключением подчеркивания. Что касается M_, это действительно просто об эстетике. Я (и многие другие) найти м_ некрасиво, как там выглядит это дыра в имени переменной. Это почти обидно. Я использовал его в VB6 все время, но это было только потому что переменные не могли иметь ведущие подчеркивания. Я не мог быть счастливее видеть, как это уходит. Microsoft рекомендует против m_ (и прямо _), хотя они оба в их коде. Кроме того, префикс с прямо "м" прямо. Конечно, так как они кодируют в основном на C #, они могут есть частные члены, которые отличаются только в случае из свойств. VB люди должен сделать что-то еще. Скорее, чем попытаться придумать по каждому языку особые случаи, я рекомендую лидирующие подчеркивания для все языки, которые будут поддерживать это. Если Я хочу, чтобы мой класс был полностью CLS-совместимый, я мог бы оставить префикс любого члена с защитой C # переменные. На практике, однако, я никогда не беспокойся об этом, так как я держу все потенциально защищенные переменные-члены частный, и поставка защищена аксессоры и мутаторы вместо. Зачем: В двух словах, это соглашение простой (один символ), легко читаемый (ваш глаз не отвлекается на других ведущие персонажи) и успешно избегает именования коллизий с переменные уровня процедуры и Свойства уровня класса. Свойства уровня класса.

5 голосов
/ 29 июня 2010

Первый комментатор (R Samuel Klatchko) ссылался: Каковы правила использования подчеркивания в идентификаторе C ++? , который отвечает на вопрос о подчеркивании в C ++. В общем, вы не должны использовать начальное подчеркивание, так как оно зарезервировано для разработчика вашего компилятора. Код, который вы видите с помощью _var, вероятно, является либо устаревшим кодом, либо кодом, написанным кем-то, кто вырос, используя старую систему именования, которая не зацикливалась на ведущих подчеркиваниях.

Как указано в других ответах, он использовался в C ++ для определения переменных членов класса. Тем не менее, он не имеет особого значения для декораторов или синтаксиса. Поэтому, если вы хотите использовать его, он скомпилируется.

Я оставлю обсуждение C # другим.

5 голосов
/ 29 июня 2010

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

В C ++ использование соглашения _var является плохим тоном, поскольку существуют правила, регулирующие использование подчеркивания перед идентификатором. _var зарезервирован как глобальный идентификатор, а _Var (подчеркивание + заглавная буква) зарезервирован в любое время. Вот почему в C ++ вы увидите людей, использующих вместо этого соглашение var_.

4 голосов
/ 29 июня 2010

Вы можете создавать свои собственные правила кодирования.Просто напишите четкую документацию для остальной части команды.

Использование _field помогает Intelilsense отфильтровывать все переменные класса, просто набирая _.

Я обычно следую Правилам Брэда Адамса , но не рекомендуется использовать подчеркивание.

2 голосов
/ 29 июня 2010

Стандарт именования Microsoft для C # гласит, что переменные и параметры должны использовать строчную букву верблюда IE: paramName.Стандарт также требует, чтобы поля имели одинаковую форму, но это может привести к неясному коду, поэтому многие команды требуют префикса подчеркивания для улучшения ясности IE: _fieldName.

2 голосов
/ 29 июня 2010

В C # Microsoft Руководство по разработке инфраструктуры предлагает не использовать символ подчеркивания для открытых членов.Для частных членов подчеркивания в порядке.Фактически, Джеффри Рихтер (часто цитируемый в руководствах) использует m_, например, и "s_" для частных статических членов.

Лично я использую только _, чтобы пометить своих частных пользователей."m_" и "s_" граничат с венгерской нотацией, которая не только не одобряется в .NET, но может быть довольно многословной, и я нахожу, что классы со многими членами трудно выполнить быструю проверку в алфавитном порядке (представьте 10 переменных, все начинающиеся с m_).

1 голос
/ 29 июня 2010

Я использую именование _var для переменных-членов моих классов. У меня есть две основные причины:

1) Это помогает мне отслеживать переменные класса и локальные функции, когда я читаю свой код позже.

2) Это помогает в Intellisense (или другой системе дополнения кода), когда я ищу переменную класса. Знание первого символа полезно для фильтрации списка доступных переменных и методов.

1 голос
/ 29 июня 2010

Что касается языков C и C ++, то нет особого значения для подчеркивания в имени (начало, середина или конец).Это просто допустимый символ имени переменной.«Соглашения» происходят из практики кодирования в сообществе программистов.

Как уже указывалось различными примерами выше, _ в начале может означать закрытые или защищенные члены класса в C ++.

Я просто приведу немного истории, которая может быть интересной мелочи.В UNIX, если у вас есть основная библиотечная функция C и серверная часть ядра, где вы хотите также представить функцию ядра пользовательскому пространству, _ застревает перед заглушкой функции, которая вызывает функцию ядра напрямую, не делая ничего другого.Наиболее известный и знакомый пример этого - exit () vs _exit () в ядрах типа BSD и SysV: там exit () выполняет работу с пользовательским пространством перед вызовом службы выхода ядра, тогда как _exit просто сопоставляется со службой выхода ядра.

Таким образом, _ использовался для «локальных» вещей, в данном случае локальный, являющийся машинным.Обычно _functions () не были переносимыми.В этом случае не следует ожидать одинакового поведения на разных платформах.

Теперь, что касается _ в именах переменных, таких как

int _foo;

Ну, психологически, _ - это странная вещь, которую нужно вводить в начале.Поэтому, если вы хотите создать имя переменной, которое будет иметь меньшую вероятность столкновения с чем-то другим, ОСОБЕННО при работе с заменами препроцессора вы хотите рассмотреть использование _.

Мой основной совет будет всегдаследуйте правилам вашего сообщества программистов, чтобы вы могли более эффективно сотрудничать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...