Зачем использовать префиксы для переменных-членов в классах C ++ - PullRequest
135 голосов
/ 04 августа 2009

Большая часть кода на C ++ использует синтаксические соглашения для разметки переменных-членов. Общие примеры включают

  • m_ memberName для открытых участников (где публичные участники используются вообще)
  • _ memberName для частных пользователей или всех участников

Другие пытаются принудительно использовать это -> member всякий раз, когда используется переменная-член.

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

На других языках эти соглашения гораздо менее распространены. Я вижу это только в коде Java или C #. Я думаю, что никогда не видел этого в коде Ruby или Python. Таким образом, кажется, что с более современными языками существует тенденция не использовать специальную разметку для переменных-членов.

Это соглашение все еще полезно сегодня в C ++ или это просто анахронизм. Тем более, что он так непоследовательно используется в разных библиотеках. Разве другие языки не показали, что можно обходиться без префиксов участников?

Ответы [ 28 ]

5 голосов
/ 04 августа 2009

Другие пытаются принудительно использовать this-> member всякий раз, когда участник используется переменная

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

Итак, да, я думаю, префиксы все еще полезны. Я, например, предпочел бы напечатать '_' для доступа к члену, а не 'this ->'.

5 голосов
/ 04 августа 2009

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

4 голосов
/ 04 августа 2009

Другие языки будут использовать соглашения о кодировании, они просто имеют тенденцию быть разными. Например, в C #, вероятно, есть два разных стиля, которые обычно используют люди: один из методов C ++ (_variable, mVariable или другой префикс, такой как венгерская нотация), или то, что я называю методом StyleCop.

private int privateMember;
public int PublicMember;

public int Function(int parameter)
{
  // StyleCop enforces using this. for class members.
  this.privateMember = parameter;
}

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

В моем примере выше вам не нужен префикс m для переменных-членов, потому что вы используете префикс перед этим. указывает то же самое в методе с применением компилятора.

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

3 голосов
/ 04 августа 2009

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

3 голосов
/ 04 августа 2009

Первоначальная идея префиксов в переменных-членах C ++ заключалась в том, чтобы хранить дополнительную информацию о типах, о которой компилятор не знал. Так, например, у вас может быть строка фиксированной длины символов, а другая переменная, оканчивающаяся на «\ 0». Для компилятора они оба char *, но если вы попытаетесь скопировать данные с одного на другое, у вас возникнут огромные проблемы. Итак, с моей головы,

char *aszFred = "Hi I'm a null-terminated string";<br> char *arrWilma = {'O', 'o', 'p', 's'};

, где "asz" означает, что эта переменная является "строкой ascii (с нулевым окончанием), а" arr "означает, что эта переменная является массивом символов.

Тогда происходит волшебство. Компилятор будет очень доволен этим утверждением:

strcpy(arrWilma, aszFred);

Но вы, как человек, можете посмотреть на это и сказать: «Эй, эти переменные на самом деле не одного типа, я не могу этого сделать».

К сожалению, во многих местах используются стандарты, такие как "m_" для переменных-членов, "i" для целых чисел независимо от того, как они используются, "cp" для указателей на символы. Другими словами, они дублируют то, что знает компилятор, и в то же время затрудняют чтение кода. Я считаю, что эта пагубная практика должна быть запрещена законом и подлежать суровым наказаниям.

Наконец, я должен упомянуть два момента:

  • Разумное использование функций C ++ позволяет компилятору знать информацию, которую вы должны были закодировать в необработанных переменных в стиле C. Вы можете создавать классы, которые будут разрешать только допустимые операции. Это должно быть сделано настолько практичным, насколько это возможно.
  • Если ваши блоки кода настолько длинные, что вы забыли, какого типа переменная, прежде чем использовать ее, они будут way слишком длинными. Не используйте имена, реорганизуйте.
3 голосов
/ 04 августа 2009

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

В течение многих лет я работал надбольшая база кода, которая использует как соглашение "this->", так и использование нотации подчеркивания postfix для переменных-членов.На протяжении многих лет я также работал над небольшими проектами, некоторые из которых не имели каких-либо соглашений для именования переменных-членов, а другие имели разные соглашения для именования переменных-членов.Из этих небольших проектов я всегда находил те, в которых отсутствовало какое-либо соглашение, наиболее трудным для быстрого понимания и понимания.

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

Последний пункт в теме IDEделать работу - это все хорошо, но IDE часто недоступны в тех средах, где я выполняю самую неотложную работу.Иногда единственная вещь, доступная на тот момент, - это копия «vi».Кроме того, я видел много случаев, когда завершение кода IDE распространяло глупость, такую ​​как неправильное написание в именах.Поэтому я предпочитаю не полагаться на костыль IDE.

3 голосов
/ 04 августа 2009

ИМО, это личное. Я не ставлю никаких префиксов вообще. В любом случае, если код должен быть общедоступным, я думаю, что он должен иметь некоторые префиксы, чтобы он мог быть более читабельным.

Часто крупные компании используют свои собственные так называемые «правила разработчика».
Кстати, самым забавным, но самым умным из тех, что я видел, был СУХОЙ ПОЦЕЛУЙ (не повторяйся. Оставайся простым, глупый) : -)

3 голосов
/ 04 августа 2009

Наш проект всегда использовал «свое» в качестве префикса для данных элементов и «» в качестве префикса для параметров, без префикса для локальных. Это немного неприятно, но это было принято ранними разработчиками нашей системы, потому что они видели, что она использовалась как соглашение некоторыми коммерческими исходными библиотеками, которые мы использовали в то время (или XVT, или RogueWave - возможно, оба). Таким образом, вы получите что-то вроде этого:

void
MyClass::SetName(const RWCString &theName)
{
   itsName = theName;
}

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

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

Что касается самого его / самого - мне, честно говоря, легче печатать, чем подчеркивания (как машинистка на ощупь, я стараюсь избегать подчеркиваний, когда это возможно - слишком много растягивающихся над домашними строками), и я нахожу его более читабельным, чем таинственный подчеркивание.

2 голосов
/ 04 августа 2009

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

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

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

2 голосов
/ 16 ноября 2009

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

...