Вопрос

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

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

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

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

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

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

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

Использованная литература:

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

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

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

Спасибо!

Это было полезно?

Решение

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

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

Другие советы

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Все зависит от личных предпочтений.Я работал в двух компаниях с похожими схемами, где переменные-члены называются m_varName.Я никогда не видел, чтобы венгерская нотация использовалась на работе, и мне она действительно не нравится, но опять же по предпочтениям.Я считаю, что IDE должна позаботиться о том, чтобы сообщить вам, какой это тип, поэтому, пока имя достаточно описывает то, что он делает ( m_color, m_shouldBeRenamed ), тогда это нормально.Еще мне нравится разница между переменной-членом, локальной переменной и именованием констант, поэтому легко увидеть, что происходит в функции и откуда берутся переменные.Член:m_varname const:c_varname local:имя_переменной

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

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;
};

Видеть Стандартное руководство по высокоинтегральному программированию на C++ для еще большего вдохновения.

Наша команда использует Соглашение о коде Google C++:

Это пример имени переменной:

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

string tableName;   // Bad - mixed case.

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top