Рекомендации по улучшению кода
Каким рекомендациям вы следуете, чтобы улучшить общее качество вашего кода? У многих людей есть правила о том, как писать код C++, которые (предположительно) затрудняют ошибки. Я видел, как людинастаивают , что за каждым утверждениемif следует блок скобок ({...}).
Меня интересует, каким руководящим принципам следуют другие люди, и причины, стоящие за ними. Меня также интересуют рекомендации, которые вы считаете ерундой, но которые обычно соблюдаются. Может ли кто-нибудь предложить мало?
Чтобы заставить мяч катиться, я упомяну несколько для начала:
- всегда используйте фигурные скобки после каждого
if/elseзаявление (упомянутое выше). Это объясняется тем, что не всегда легко определить, является ли один оператор на самом деле одним оператором или макросом препроцессора, который расширяется до нескольких операторов, поэтому этот код будет нарушен:
// top of file:
#define statement doSomething(); doSomethingElse
// in implementation:
if (somecondition)
doSomething();
Но если вы используете фигурные скобки, то это будет работать, как и ожидалось.
- используйте макросы препроцессора для только условная компиляция. макросы препроцессора могут вызвать всевозможные неприятности, так как они не допускают правил определения области C++. Я много раз садился на мель из-за макросов препроцессора с общими именами в заголовочных файлах. Если вы не будете осторожны, вы можете вызвать все виды опустошения!
А теперь перейдем к вам.
21 ответов:
Несколько моих личных фаворитов:
Стремитесь написать код, который являетсяconst правильным . Вы будете привлекать компилятор, чтобы помочь отсеять легко исправимые, но иногда болезненные ошибки. Ваш код также расскажет историю о том, что вы имели в виду в то время, когда вы его писали-ценный для новичков или сопровождающих, когда вы уйдете.
Уходите из бизнеса по управлению памятью. Научитесь использовать умные указатели:
std::auto_ptr,std::tr1::shared_ptr(илиboost::shared_ptr) иboost::scoped_ptr. Узнайте различия между ними и когда использовать одно против другого.Вы, вероятно, будете использовать стандартную библиотеку шаблонов. Прочитайте книгуJosuttis . Не останавливайтесь после первых нескольких глав о контейнерах, думая, что вы знаете STL. Переходите к хорошим вещам: алгоритмам и функциональным объектам.
- Используйте и применяйте общий стиль кодирования и руководящие принципы. обоснование: каждый разработчик в команде или в фирме может читать код без отвлекающих факторов, которые могут возникнуть из-за различных стилей скобок или аналогичных.
- Регулярно выполняйте полную перестройку всей вашей исходной базы (т. е. выполняйте ежедневные сборки или сборки после каждой проверки) и сообщайте о любых ошибках! обоснование: Источник почти всегда находится в работоспособном состоянии, и проблемы обнаруживаются вскоре после того, как они "реализовано", где решение проблем дешево.
Включите все предупреждения, которые могут стоять в вашем компиляторе (gcc:
-Wallявляется хорошим началом, но не включает все, поэтому проверьте документы), и сделайте их ошибки, так что вы должны исправить их (gcc:-Werror).
Руководство по стилю Google, упомянутое в одном из этих ответов, довольно солидно. Там есть кое-что бессмысленное, но это скорее хорошо, чем плохо.
Саттер и Александреску написали приличную книгу на эту тему, названнуюC++ Coding Standards .Вот несколько общих советов от lil ' ole me:
Ваш стиль отступов и брекетинга неверен. Так что все чужие. Поэтому следовать стандартам проекта для этого. Проглоти свою гордость и настрой свой редактор, чтобы все было максимально согласовано с остальной частью кодовой базы. Это действительно очень раздражает, когда приходится читать код, который имеет отступы непоследовательно. Тем не менее, брекетинг и отступы не имеют никакого отношения к "улучшению вашего кода.- Речь идет скорее об улучшении вашей способности работать с другими.
Прокомментируйте хорошо. Это крайне субъективно, но в целом всегда полезно писать комментарии о Почему код работает именно так, а не иначе. объясняя, что он делает. Конечно, для сложного кода это также хорошо для программистов, которые могут не быть знакомы с алгоритмом или кодом, чтобы иметь представление о том, что он делает. Ссылки на описания используемых алгоритмов очень приветствуются.
Выражайте логику как можно более прямолинейно. По иронии судьбы предложения типа "поместите константы на левую сторону сравнений" здесь, я думаю, пошли не так. Они очень популярны, но для носителей английского языка, они часто нарушают логический ход программы те, кто читает. Если вы не можете доверять себе (или своему компилятору), чтобы написать равенство сравнивает правильно, то во что бы то ни стало использовать трюки, подобные этому. Но вы жертвуете ясностью, когда делаете это. Также подпадают под эту категорию такие вещи, как ... "Имеет ли моя логика 3 уровня отступа? Может ли быть проще?- и скатывание подобного кода в функции. Может быть, даже разделение функций. Требуется опыт, чтобы написать код, который элегантно выражает глубинная логика, но над ней стоит поработать.
Они были довольно общими. Что касается конкретных советов, я не могу сделать намного лучше, чем Саттер и Александреску.
В операторах if константа ставится слева, т. е.
if( 12 == var )Не
if( var == 12 )Потому что если вы пропустите ввод'=', то это становится назначением. В верхней версии компилятор говорит, что это невозможно, в последней он работает, и if всегда истинно.
Я использую фигурные скобки для if, когда они не находятся на одной линии.
if( a == b ) something(); if( b == d ) { bigLongStringOfStuffThatWontFitOnASingleLineNeatly(); }Открытые и закрытые фигурные скобки всегда имеют свои собственные линии. Но это, конечно, личная условность.
Комментируйте только тогда, когда необходимо объяснить, что делает код, когда чтение кода не может сказать вам то же самое.
Не комментируйте код, который вы больше не используете. Если вы хотите восстановить старый код, используйте свою систему управления версиями. Комментируя код, вы просто создаете беспорядок, и ваши комментарии, которые на самом деле важны, исчезают в фоновом беспорядке комментируемого кода.
- Используйте последовательное форматирование.
- при работе с устаревшим кодом используйте существующий стиль форматирования, esp. стиль Брейса.
- получите копию книги Скотта Мейера Effective C++
- получите полную копию кода книги Стива Макконнелла.
Существует также хорошее руководство по стилю C++ , используемое внутри Google, которое включает в себя большинство правил, упомянутых здесь.
Начните писать много комментариев - но используйте это как возможность рефакторинга кода, чтобы он был понятен.
Ie:
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, также будет затронуто, даже если человек с вашего заголовка не хочет, чтобы все ЗППП (например) в глобальном пространстве имен.
Если что-то длиннее 80 столбцов, разбейте его на несколько строк, например
if(SomeVeryLongVaribleName != LongFunction(AnotherVarible, AString) && BigVaribleIsValid(SomeVeryLongVaribleName)) { DoSomething(); }Только перегружать операторы, чтобы заставить их делать то, что ожидает пользователь, например перегружать операторы + и - для 2dVector нормально
Всегда комментируйте свой код, даже если он просто говорит, что делает следующий блок (например, " удалите все текстуры, которые не нужны для этого уровень"). Кому-то может понадобиться поработать с ним позже, особенно после того, как вы ушли, и они не хотят найти 1000 строк кода без комментариев, чтобы указать, что и как делать.
- Установите соглашение о кодировании и заставьте всех участников следовать этому соглашению (вы не хотите читать код, который требует, чтобы вы выяснили, где находится следующий оператор / выражение, потому что он не имеет отступа должным образом)
- постоянно рефакторинг вашего кода (получить копию рефакторинга, Мартин Фаулер, плюсы и минусы подробно описаны в книге)
- напишите слабо связанный код (избегайте написания комментариев, написав самоописывающийся код, слабо связанный код, как правило, легче писать). управление / адаптация к изменениям)
- Если возможно, модульный тест вашего кода (или, если вы достаточно мачо, TDD.)
- выпускать рано, выпускать часто
- избегайте преждевременной оптимизации (профилирование помогает в оптимизации)
В том же духе вы можете найти здесь несколько полезных советов: Как заставить неправильный код выглядеть неправильно? Какие шаблоны вы используете, чтобы избежать семантических ошибок?
Я использую PC-Lint в своих проектах на C++, и особенно мне нравится, как он ссылается на существующие публикации, такие как руководство MISRA или "эффективный C++" Скотта Мейерса и "более эффективный C++". Даже если вы планируете писать очень подробные обоснования для каждого правила, которое проверяет ваш инструмент статического анализа, рекомендуется указывать на существующие публикации, которым доверяет ваш пользователь.
Вот самый важный совет, который мне дал гуру C++, и он помог мне в нескольких критических случаях найти ошибки в моем коде:
- Используйте методы const, когда методне должен изменять объект.
- Используйте ссылки и указатели const в параметрах, когда объект не должен изменять объект.
С этими 2 правилами компилятор бесплатно сообщит вам, где в вашем коде логика ошибочна!
Кроме того, для некоторых хороших методов вы можете следовать блог Google "тестирование в туалете".
Хм-я, наверное, должен был быть немного более конкретным.
Я не столько ищу советы для себя - я пишу инструмент статического анализа кода (текущие коммерческие предложения просто недостаточно хороши для того, что я хочу), и я ищу идеи для плагинов, чтобы выделить возможные ошибки в коде.
Несколько человек упоминали такие вещи, как корректность const и использование интеллектуальных указателей - это то, что я могу проверить. Проверка наличия отступов и комментариев это немного сложнее сделать (с точки зрения программирования в любом случае).
Интеллектуальные указатели имеют хороший способ очень четко указывать на принадлежность. Если вы класс или функция:
- Если вы получаете необработанный указатель, вы ничем не владеете. Вам разрешено использовать пойнт, любезно предоставленный вашим абонентом, который гарантирует, что пойнт останется в живых дольше, чем вы.
- Если вы получаетеweak_ptr , вы не являетесь владельцем точки, и, кроме того, точка может исчезнуть в любое время.
- Если вы получаете shared_ptr , вы владеете объект наряду с другими, так что вам не нужно беспокоиться. Меньше стресса, но и меньше контроля.
- Если вы получаете auto_ptr, Вы являетесь единственным владельцем объекта. Он твой, ты-король. У вас есть власть уничтожить этот объект или отдать его кому-то другому (тем самым потеряв право собственности).
Я нахожу случай auto_ptr особенно сильным: в дизайне, если я вижу auto_ptr, я сразу знаю, что этот объект будет "блуждать" от одной части системы к другой. другой.
Это, по крайней мере, логика, которую я использую в своем домашнем проекте. Я не знаю, сколько вариаций может быть на эту тему, но до сих пор этот набор правил служил мне хорошо.
Comments