Подтвердить что ты не робот

Переменные соглашения об именах в С++

Я родом из мира .NET, и я новичок в написании С++. Мне просто интересно, каковы предпочтительные соглашения об именах, когда речь идет об именах локальных переменных и членов структуры.

Например, унаследованный код, который я унаследовал, имеет много таких:

struct MyStruct
{
   TCHAR           szMyChar[STRING_SIZE];
   bool            bMyBool;
   unsigned long   ulMyLong;
   void*           pMyPointer;
   MyObject**      ppMyObjects;
}

Исходя из фона С#, я был потрясен, увидев переменные с венгерской нотацией (я не мог перестать смеяться над префиксом pp в первый раз, когда увидел это).

Я бы скорее назвал мои переменные таким образом (хотя я не уверен, что заглавная буква первой является хорошим соглашением. Я видел другие способы (см. ссылки ниже)):

struct MyStruct
{
   TCHAR           MyChar[STRING_SIZE];
   bool            MyBool;
   unsigned long   MyLong;
   void*           MyPointer;
   MyObject**      MyObjects;
}

Мой вопрос: Является ли это (прежним способом) еще предпочтительным способом для обозначения переменных в С++?

Литература:

http://geosoft.no/development/cppstyle.html

http://www.syntext.com/books/syntext-cpp-conventions.htm

http://ootips.org/hungarian-notation.html

Спасибо!

4b9b3361

Ответ 1

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

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

Ответ 2

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

Ответ 3

Нет. "Неправильная венгерская нотация" - особенно pp для двойной косвенности - имела смысл для ранних компиляторов C, где вы могли написать

int * i = 17;
int j = ***i;

без предупреждения от компилятора (и это может быть даже допустимым кодом на нужном оборудовании...).

"Истинная венгерская нотация" (как указано в главе Geek) - это ИМО, все еще действительный вариант, но не обязательно предпочтительный. Современное приложение на С++ обычно имеет десятки или сотни типов, для которых вы не найдете подходящих префиксов.

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

float fXmin, fXmax, fXpeak; // x values of range and where y=max
int   iXmin, iXMax, iXpeak; // respective indices in x axis vector

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

Мое рассуждение: Цель стандартов кодирования - соблюдать принцип наименьшего удивления. Использование одного стиля последовательно более важно, чем стиль, который вы используете.

Ответ 4

Что не нравится или издевается над "ppMyObjects" в этом примере, кроме того, что он несколько уродлив? У меня нет сильных мнений в любом случае, но он обменивается полезной информацией с первого взгляда, что "MyObjects" этого не делает.

Ответ 5

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

Элементы класса/структуры должны выделяться - я обычно префикс их всех m_
Глобальные переменные должны выделяться - префикс usuall с g_
Переменные в целом должны начинаться с нижнего регистра
Названия функций в общем случае должны начинаться с верхнего регистра
Макросы и, возможно, перечисления должны быть все в верхнем регистре
Все имена должны описывать, что делает функция/переменная, и никогда не должны описывать ее тип или значение.

Ответ 6

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

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

Ответ 7

Венгерская нотация была распространена среди пользователей API Win32 и MFC. Если ваши предшественники использовали это, вы, вероятно, лучше всего сможете его использовать (даже если это отстой). В остальной части мира С++ никогда не было такого мозгового соглашения, поэтому не используйте его, если вы используете нечто иное, чем эти API.

Ответ 8

Я думаю, что вы все равно обнаружите, что большинство магазинов, которые программируют на Visual С++, придерживаются венгерской нотации или, по крайней мере, ее политой. В нашем магазине половина нашего приложения - это устаревший С++ с блестящим новым С# -слоем сверху (с управляемым уровнем С++ посередине.) Наш код на С++ продолжает использовать венгерскую нотацию, но наш код С# использует нотацию, представленную вами. Я думаю, что это уродливо, но это непротиворечиво.

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

Ответ 9

Все сводится к личным предпочтениям. Я работал в двух компаниях с аналогичными схемами, где члены vars называются m_varName. Я никогда не видел, чтобы венгерская нотация использовалась на работе, и ей это действительно не нравится, но опять же к предпочтению. Мое общее мнение состоит в том, что IDE должна позаботиться о том, чтобы сказать, какой тип он есть, до тех пор, пока имя достаточно описательно для того, что он делает (m_color, m_shouldBeRenamed), тогда это нормально. Другая вещь, которая мне нравится, - это разница между переменной-членом, локальным var и постоянным наименованием, поэтому ее легко увидеть, что происходит в функции и откуда возникают вары. Участник: m_varName Const: c_varName local: varName

Ответ 10

Я также предпочитаю CamelCase, действительно, в основном я видел людей, использующих CamelCase на С++. Personaly Я не использую никаких префиксов для частных/защищенных членов и интерфейсов:

class MyClass : public IMyInterface {
public:
    unsigned int PublicMember;
    MyClass() : PublicMember(1), _PrivateMember(0), _ProtectedMember(2) {}
    unsigned int PrivateMember() {
        return _PrivateMember * 1234; // some senseless calculation here
    }
protected:
    unsigned int _ProtectedMember;
private:
    unsigned int _PrivateMember;
};
// ...
MyClass My;
My.PublicMember = 12345678;

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

struct IMyInterface {
    virtual void MyVirtualMethod() = 0;
};

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

struct IMyInterfaceAsAbstract abstract {
    virtual void MyVirtualMethod() = 0;
    virtual void MyImplementedMethod() {}
    unsigned int EvenAnPublicMember;
};

Подробнее см. Стандартное руководство по кодированию High Integrity С++.

Ответ 11

Моя команда придерживается этого правила Google C++:

Это образец имени переменной:

string table_name;  // OK - uses underscore.
string tablename;   // OK - all lowercase.

string tableName;   // Bad - mixed case.

Ответ 12

Если вы используете CamelCase, соглашение состоит в том, чтобы использовать первую букву для классов struct и non primitive имен типов, а в нижнем регистре - первая буква для членов данных. Капитализация методов имеет тенденцию быть смешанной сумкой, мои методы, как правило, являются глаголами и уже отчуждены parens, поэтому я не использую методы.

Лично я не люблю читать код CamelCase и предпочитаю подчеркивать нижний регистр для идентификаторы данных и методов, типы заглавных букв и резервирование прописных букв для аббревиатур и редкий случай, когда я использую макрос (предупреждение это MACRO).