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

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

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

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

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

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

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

Ответы [ 28 ]

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

Я использую его, потому что IntelliSense VC ++ не может сказать, когда показывать приватных членов при доступе вне класса. Единственным указанием является небольшой символ «блокировки» на значке поля в списке Intellisense. Это просто облегчает идентификацию частных членов (полей). Также привычка из C #, если честно.

class Person {
   std::string m_Name;
public:
   std::string Name() { return m_Name; }
   void SetName(std::string name) { m_Name = name; }
};

int main() {
  Person *p = new Person();
  p->Name(); // valid
  p->m_Name; // invalid, compiler throws error. but intellisense doesn't know this..
  return 1;
}
1 голос
/ 25 сентября 2015

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

color = Red;

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

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

В основном, я использую 'this' только в конструкторах и инициализаторах.

1 голос
/ 05 декабря 2013

Вам никогда не понадобится такой префикс. Если такой префикс дает вам какое-либо преимущество, ваш стиль кодирования в целом нуждается в исправлении, и это не тот префикс, который удерживает ваш код от ясности. Типичные неправильные имена переменных включают в себя «other» или «2». Вы не исправляете это, требуя, чтобы это было mOther, вы исправляете это, заставляя разработчика думать о том, что эта переменная делает там в контексте этой функции. Возможно, он имел в виду remoteSide, newValue, secondTestListener или что-то в этом роде.

Это эффективный анахронизм, который все еще распространяется слишком далеко. Прекратите префикс ваших переменных и дайте им имена, чья ясность отражает, как долго они используются. До 5 строк вы можете назвать это «я» без путаницы; за 50 строк нужно довольно длинное имя.

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

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

1 голос
/ 05 августа 2009

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

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

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

Code Complete рекомендует m_varname для переменных-членов.

Хотя я никогда не думал, что нотация m_ полезна, я бы учел мнение Макконнелла при разработке стандарта.

0 голосов
/ 05 апреля 2018

Согласно СТАНДАРТАМ КОДИРОВАНИЯ ВОЗДУШНОГО АВТОМОБИЛЯ FIGHTER C ++ (декабрь 2005)

AV Правило 67

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

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

Но стоит использовать префикс p перед указателем, поскольку это опасная переменная.

0 голосов
/ 30 апреля 2017

Я использую m_ для переменных-членов просто для того, чтобы воспользоваться Intellisense и связанной с ним IDE-функциональностью Когда я пишу реализацию класса, я могу набрать m_ и увидеть комбинированный список со всеми членами m_, сгруппированными вместе.

Но я мог бы без проблем жить без проблем, конечно. Это просто мой стиль работы.

...