Рекомендации по улучшению вашего кода
Какими рекомендациями вы руководствуетесь, чтобы улучшить общее качество своего кода? У многих людей есть правила о том, как писать код на C++, который (предположительно) затрудняет ошибки. Я видел, как люди настаивают на том, что каждый if
за оператором следует блок скобок ({...}
).
Мне интересно, какие руководящие принципы придерживаются другие люди, и причины их возникновения. Я также заинтересован в руководящих принципах, которые вы считаете мусором, но обычно придерживаются. Кто-нибудь может предложить несколько?
Чтобы начать движение, я упомяну несколько для начала:
- Всегда используйте брекеты после каждого
if
/else
заявление (упомянутое выше). Это объясняется тем, что не всегда легко определить, является ли один оператор фактически одним оператором или макросом препроцессора, который расширяется до нескольких операторов, поэтому этот код будет нарушен:
// начало файла: #define инструкция doSomething(); doSomethingElse // в реализации: if (somecondition) doSomething();
но если вы используете скобки, то это будет работать, как ожидалось.
- Используйте макросы препроцессора ТОЛЬКО для условной компиляции. Макросы препроцессора могут вызывать все виды ада, так как они не допускают применения правил C++. Я много раз запускался на мель из-за макросов препроцессора с общими именами в заголовочных файлах. Если вы не будете осторожны, вы можете причинить много вреда!
Теперь к вам.
21 ответ
Несколько из моих личных любимых:
Стремитесь писать код, который является правильным. Вы заручитесь поддержкой компилятора, чтобы избавиться от несложных, но иногда болезненных ошибок. Ваш код также расскажет вам историю о том, что вы имели в виду во время написания этого документа. Это полезно для новичков или сопровождающих, когда вы уйдете.
Выйдите из бизнеса по управлению памятью. Научитесь использовать умные указатели: std::auto_ptr
, std::tr1::shared_ptr
(или же boost::shared_ptr
) а также boost::scoped_ptr
, Узнайте различия между ними и когда использовать один против другого.
Вы, вероятно, собираетесь использовать стандартную библиотеку шаблонов. Прочитайте книгу Josuttis. Не останавливайтесь после первых нескольких глав о контейнерах, думая, что вы знаете STL. Перейдите к хорошему: алгоритмам и функциональным объектам.
Включите все предупреждения, которые вы можете оставить в вашем компиляторе (gcc: -Wall
это хорошее начало, но не включает в себя все, поэтому проверьте документы), и сделайте их ошибки, так что вы должны исправить их (gcc: -Werror
).
- Используйте и применяйте общий стиль кодирования и рекомендации. Обоснование: каждый разработчик в команде или в фирме может читать код без отвлекающих факторов, которые могут возникнуть из-за разных стилей скобок или аналогичных.
- Регулярно делайте полную перестройку всей вашей исходной базы (т.е. делайте ежедневные сборки или сборки после каждой регистрации) и сообщайте о любых ошибках! Обоснование: источник почти всегда находится в работоспособном состоянии, и проблемы обнаруживаются вскоре после того, как они "реализованы", где решение проблем обходится дешево.
Руководство по стилю Google, упомянутое в одном из этих ответов, довольно солидно. В этом есть что-то бессмысленное, но это скорее хорошо, чем плохо.
Саттер и Александреску написали достойную книгу на эту тему под названием " Стандарты кодирования C++".
Вот несколько общих советов от меня:
Ваш отступ и стиль брекетинга неверны. Как и все остальные. Так что следуйте стандартам проекта для этого. Поглотите свою гордость и настройте свой редактор так, чтобы все было максимально согласовано с остальной базой кода. Это действительно очень раздражает необходимость читать код с непоследовательным отступом. Тем не менее, скобки и отступы не имеют никакого отношения к "улучшению вашего кода". Это больше об улучшении вашей способности работать с другими.
Комментируйте хорошо. Это очень субъективно, но в целом всегда полезно писать комментарии о том, почему код работает так, как он работает, а не объяснять, что он делает. Конечно, для сложного кода программистам, которые могут быть не знакомы с алгоритмом или кодом, также полезно иметь представление о том, что он делает. Ссылки на описания используемых алгоритмов приветствуются.
Выразите логику как можно проще. По иронии судьбы, такие предложения, как "поставить константы в левую часть сравнений", на мой взгляд, ошиблись. Они очень популярны, но для носителей английского языка они часто нарушают логический поток программы для тех, кто читает. Если вы не можете доверять себе (или своему компилятору), чтобы написать равенство, сравнение корректно, тогда непременно используйте подобные приемы. Но вы жертвуете ясностью, когда делаете это. Также подпадают под эту категорию такие вещи, как... "Есть ли в моей логике 3 уровня отступа? Может ли быть проще?" и свернуть подобный код в функции. Может быть, даже разделение функций. Для написания кода, который элегантно выражает основную логику, нужен опыт, но над этим стоит поработать.
Это были довольно общие. Для конкретных советов я не могу сделать намного лучше, чем Саттер и Александреску.
В операторах if ставим константу слева, т.е.
if( 12 == var )
не
if( var == 12 )
Поскольку, если вы пропустите ввод '=', тогда это станет назначением. В верхней версии компилятор говорит, что это невозможно, в последней он запускается, и if всегда имеет значение true.
Я использую скобки для if, если они не находятся на одной строке.
if( a == b ) something();
if( b == d )
{
bigLongStringOfStuffThatWontFitOnASingleLineNeatly();
}
Открытые и закрытые скобки всегда получают свои собственные линии. Но это, конечно, личное соглашение.
Комментируйте только тогда, когда необходимо объяснить, что делает код, когда чтение кода не может сказать вам то же самое.
Не закомментируйте код, который вы больше не используете. Если вы хотите восстановить старый код, используйте систему контроля версий. Комментирование кода просто делает вещи беспорядочными, а ваши комментарии, которые на самом деле важны, переходят в фоновый беспорядок комментируемого кода.
Существует также хорошее руководство по стилю C++, используемое Google для внутреннего использования, которое включает в себя большинство упомянутых здесь правил.
- Используйте последовательное форматирование.
- При работе с унаследованным кодом используйте существующий стиль форматирования, особенно Брейс стиль.
- Получить копию книги Скотта Мейера "Эффективный C++"
- Получите копию книги Стива Маконнелла Code Complete.
Начните писать много комментариев - но используйте это как возможность реорганизовать код, чтобы он стал понятен.
то есть:
for(int i=0; i<=arr.length; i++) {
arr[i].conf() //confirm that every username doesn't contain invalid characters
}
Должно быть что-то вроде
for(int i=0; i<=activeusers.length; i++) {
activeusers[i].UsernameStripInvalidChars()
}
В том же духе вы можете найти здесь несколько полезных советов: как сделать неправильный код неправильным? Какие шаблоны вы используете, чтобы избежать семантических ошибок?
Используйте вкладки для отступов, но выравнивайте данные с пробелами. Это означает, что люди могут решать, сколько отступов, изменяя размер вкладки, но также и то, что все остается выровненным (например, вы можете захотеть, чтобы все '=' в вертикальной линии при назначении значений для структура)
Всегда используйте константы или встроенные функции вместо макросов, где это возможно
Никогда не используйте 'using' в заголовочных файлах, потому что все, что включает этот heafer, также будет затронуто, даже если человек, включающий ваш заголовок, не хочет, чтобы все std (например) были в их глобальном пространстве имен.
Если что-то длиннее 80 столбцов, разбейте их на несколько строк, например
if(SomeVeryLongVaribleName != LongFunction(AnotherVarible, AString) && BigVaribleIsValid(SomeVeryLongVaribleName)) { DoSomething(); }
Только операторы перегрузки, чтобы заставить их делать то, что ожидает пользователь, например, перегрузка операторов + и - для 2dVector - это хорошо.
Всегда комментируйте свой код, даже если он просто говорит, что делает следующий блок (например, "удалите все текстуры, которые не нужны для этого уровня"). Кому-то может понадобиться поработать с ним позже, возможно, после того, как вы уйдете, и они не хотят находить тысячи строк кода без комментариев, чтобы указать, что и что делает.
Вот самый важный совет, который мне дал гуру C++, и он помог мне в нескольких критических случаях найти ошибки в моем коде:
- Используйте методы const, когда метод не должен изменять объект.
- Используйте константные ссылки и указатели в параметрах, когда объект не должен изменять объект.
С этими двумя правилами компилятор бесплатно сообщит вам, где в вашем коде есть недостатки!
Кроме того, для некоторых хороших методов вы могли бы следовать блогу Google "Тестирование в туалете".
Я использую PC-Lint в своих проектах на C++ и особенно в том, что касается ссылок на существующие публикации, такие как рекомендации MISRA или "Эффективный C++" и "Более эффективный C++" Скотта Мейерса. Даже если вы планируете писать очень подробные обоснования для каждого правила, которое проверяет ваш инструмент статического анализа, рекомендуется указать на установленные публикации, которым доверяет ваш пользователь.
- настройте соглашение о кодировании и заставьте всех участников следовать соглашению (вам не нужно читать код, который требует, чтобы вы выяснили, где находится следующий оператор / выражение, потому что он не имеет правильного отступа)
- постоянный рефакторинг вашего кода (получите копию Refactoring, Martin Fowler, плюсы и минусы подробно описаны в книге)
- писать слабосвязанный код (избегайте написания комментариев, написав понятный код, слабосвязанный код легче управлять / адаптировать к изменениям)
- если возможно, проведите модульное тестирование своего кода (или, если вы достаточно мачо, TDD.)
- выпускать раньше, выпускать часто
- избегать преждевременной оптимизации (профилирование помогает в оптимизации)
Где вы можете использовать пре-инкремент вместо пост-инкремента.
Стандарты кодирования C# и соглашения об именах
Ниже приведены наши стандарты кодирования C#, соглашения об именах и лучшие практики. Используйте их в своих собственных проектах и / или подгоняйте под свои нужды.
Соглашения об именах и стиль
используйте PascalCasing для имен классов и методов.
Почему: соответствует Microsoft.NET Framework и легко читается.
используйте camelCasing для аргументов метода и локальных переменных.
Почему: соответствует Microsoft.NET Framework и легко читается.
не: используйте венгерскую запись или любую другую идентификацию типа в идентификаторах
Почему: в соответствии с.NET Framework и IDE Visual Studio делает определение типов очень простым (с помощью подсказок). В общем, вы хотите избежать указателей типа в любом идентификаторе.
не используйте Screaming Caps для констант или переменных только для чтения
Прочитайте больше о "C# Coding Coding Standards и Naming Convention" с примером здесь
Умные указатели имеют хороший способ очень четко указать право собственности. Если вы класс или функция:
- если вы получаете необработанный указатель, вы ничего не имеете. Вам разрешено использовать pointee, любезно предоставленный вашим абонентом, который гарантирует, что pointee будет жить дольше, чем вы.
- если вы получили слабый_птр, вы не владеете pointee, и, кроме того, pointee может исчезнуть в любое время.
- если вы получаете shared_ptr, вы владеете объектом вместе с другими, так что вам не о чем беспокоиться. Меньше стресса, но и меньше контроля.
- если вы получаете auto_ptr, вы являетесь единственным владельцем объекта. Это твой, ты король. У вас есть сила, чтобы уничтожить этот объект или передать его кому-то другому (тем самым потеряв право собственности).
Я нахожу аргумент в пользу auto_ptr особенно сильным: в проекте, если я вижу auto_ptr, я сразу же узнаю, что этот объект будет "бродить" из одной части системы в другую.
Это, по крайней мере, логика, которую я использую в своем любимом проекте. Я не уверен, сколько вариаций может быть по теме, но до сих пор этот набор правил хорошо мне служил.
Хм - наверное, мне следовало быть более конкретным.
Я не очень ищу советы для себя - я пишу инструмент для статического анализа кода (текущие коммерческие предложения не достаточно хороши для того, что я хочу), и я ищу идеи для плагинов, чтобы выделить возможные ошибки в коде.
Несколько человек упомянули такие вещи, как правильность констант и использование умных указателей - вот тип, который я могу проверить. Проверять отступы и комментировать немного сложнее (во всяком случае, с точки зрения программирования).