Каким рекомендациям вы следуете, чтобы улучшить общее качество вашего кода? У многих людей есть правила написания кода на C++, которые (предположительно) затрудняют совершение ошибок. Я видел людей настаивать, что за каждым оператором if следует фигурная скобка ({...}).
Меня интересует, каким руководящим принципам следуют другие люди, и их причины. Меня также интересуют руководящие принципы, которые, по вашему мнению, являются вздором, но обычно соблюдаются. Кто-нибудь может предложить несколько?
Чтобы начать работу, я упомяну несколько для начала:
if / else (упомянутого выше). Обоснование этого заключается в том, что не всегда легко определить, является ли один оператор на самом деле одним оператором или макросом препроцессора, который расширяется до нескольких операторов, поэтому этот код сломается:
// top of file:
#define statement doSomething(); doSomethingElse
// in implementation:
if (somecondition)
doSomething();
но если вы используете фигурные скобки, все будет работать должным образом.
Теперь к вам.





убедитесь, что вы делаете отступы правильно
Несколько моих личных фаворитов:
Стремитесь писать код, который является const правильно. Вы привлечете компилятор, который поможет отсеять легко исправляемые, но иногда болезненные ошибки. Ваш код также расскажет о том, что вы имели в виду во время его написания - это будет полезно для новичков или сопровождающих, когда вы уйдете.
Откажитесь от бизнеса по управлению памятью. Научитесь использовать интеллектуальные указатели: std::auto_ptr, std::tr1::shared_ptr (или boost::shared_ptr) и boost::scoped_ptr. Узнайте о различиях между ними и о том, когда использовать одно по сравнению с другим.
Вероятно, вы собираетесь использовать стандартную библиотеку шаблонов. Прочтите Книга Джозаттиса. Не останавливайтесь после нескольких первых глав о контейнерах, думая, что вы знакомы с STL. Переходите к хорошему: алгоритмам и функциональным объектам.
В операторах if константа помещается слева, т.е.
if ( 12 == var )
нет
if ( var == 12 )
Потому что, если вы не наберете '=', это станет присваиванием. В верхней версии компилятор говорит, что это невозможно, в последней он выполняется, и if всегда истинно.
Я использую фигурные скобки для if, когда они не находятся в одной строке.
if ( a == b ) something();
if ( b == d )
{
bigLongStringOfStuffThatWontFitOnASingleLineNeatly();
}
Открывающая и закрывающая фигурные скобки всегда имеют собственные линии. Но это, конечно, личное соглашение.
Это одна из причин, почему мне нравится VB.Net. Операторы If не принимают присваивания, и вы можете просто использовать знак = для присваивания и проверки на равенство. Это делает некоторый код более подробным, но означает, что многие из этих ошибок просто не могут произойти.
В том же духе вы можете найти здесь несколько полезных предложений: Как сделать так, чтобы неправильный код выглядел неправильно? Какие шаблоны вы используете, чтобы избежать семантических ошибок?
Используйте табуляцию для отступов, но выравнивайте данные с пробелами Это означает, что люди могут решить, насколько сильно отступить, изменив размер табуляции, но также, чтобы все оставалось выровненным (например, вы можете захотеть, чтобы все '=' в вертикальной линии при присвоении значений структуре)
Всегда используйте константы или встроенные функции вместо макросов, где это возможно.
Никогда не используйте 'using' в файлах заголовков, потому что все, что включает этот заголовок, также будет затронуто, даже если человек, включающий ваш заголовок, не хочет, чтобы все std (например) в своем глобальном пространстве имен.
Если что-то длиннее 80 столбцов, разбейте его на несколько строк, например
if (SomeVeryLongVaribleName != LongFunction(AnotherVarible, AString) &&
BigVaribleIsValid(SomeVeryLongVaribleName))
{
DoSomething();
}
Только операторы перегрузки, чтобы заставить их делать то, что ожидает пользователь, например, перегрузка операторов + и - для 2dVector - это нормально.
Всегда комментируйте свой код, даже если он просто говорит, что делает следующий блок (например, «удалите все текстуры, которые не нужны для этого уровня»). Кому-то, возможно, придется поработать с ним позже, возможно, после того, как вы уйдете, и они не захотят найти тысячи строк кода без комментариев, чтобы указать, что и что делает.
Это все.
... Затем я получаю ошибку компилятора: ненужная функция () undefined.
Бонусные баллы за удаление всего ненужного кода с помощью функции рекурсивного удаления.
Комментируйте только тогда, когда необходимо только объяснить, что делает код, когда чтение кода не может сказать вам то же самое.
Не комментируйте код, который вы больше не используете. Если вы хотите восстановить старый код, используйте свою систему управления версиями. Комментирование кода просто делает вещи беспорядочными, и ваши комментарии, которые на самом деле важны, растворяются в фоновом беспорядке прокомментированного кода.
Включите все предупреждения, которые вы можете выставить в своем компиляторе (gcc: -Wall - хорошее начало, но не включает все, поэтому проверьте документы) и сделайте их ошибками, чтобы их нужно было исправить (gcc: -Werror).
Хм - наверное, мне следовало быть более конкретным.
Я не столько ищу совета для себя - я пишу инструмент статического анализа кода (текущие коммерческие предложения просто недостаточно хороши для того, что я хочу), и я ищу идеи для плагинов, чтобы выделить возможные ошибки в коде.
Несколько человек упомянули такие вещи, как правильность констант и использование умных указателей - это то, что я могу проверить. Проверить наличие отступов и комментариев немного сложнее (во всяком случае с точки зрения программирования).
Томи, как насчет обнаружения синглтона: code.google.com/p/google-singleton-detector
Существует также замечательный Руководство по стилю C++, используемый внутри Google, который включает в себя большинство правил, упомянутых здесь.
Руководство по стилю Google, упомянутое в одном из этих ответов, довольно надежное. В этом есть что-то бессмысленное, но это скорее хорошо, чем плохо.
Саттер и Александреску написали на эту тему достойную книгу под названием Стандарты кодирования C++.
Вот несколько общих советов от lil 'ole me:
Ваш стиль отступов и скобок неправильный. Как и все остальные. Так что следуйте стандартам проекта для этого. Проглотите свою гордость и настройте свой редактор так, чтобы все было максимально согласовано с остальной кодовой базой. Это действительно очень раздражает, когда приходится читать код с непоследовательным отступом. Тем не менее, скобки и отступы не имеют никакого отношения к «улучшению вашего кода». Это больше касается улучшения вашей способности работать с другими.
Хорошо комментируйте. Это крайне субъективно, но в целом всегда лучше писать комментарии о том, что код Почему работает именно так, а не объяснять, что он делает. Конечно, для сложного кода программистам, которые, возможно, не знакомы с алгоритмом или кодом, также полезно иметь представление о том, что Какие тоже делает. Ссылки на описания используемых алгоритмов приветствуются.
Выражайте логику как можно проще. По иронии судьбы, такие предложения, как «поместить константы в левую часть сравнений», я думаю, здесь не увенчались успехом. Они очень популярны, но для англоговорящих они часто нарушают логику программы для читающих. Если вы не можете доверять себе (или своему компилятору) написать, что равенство сравнивается правильно, то во что бы то ни стало используйте подобные уловки. Но когда вы это делаете, вы жертвуете ясностью. Также в эту категорию попадают такие вещи, как ... «Имеет ли моя логика 3 уровня отступов? Может быть проще?» и вставка аналогичного кода в функции. Возможно даже разделение функций. Для написания кода, элегантно выражающего основную логику, требуется опыт, но над этим стоит поработать.
Это были довольно общие черты. По конкретным советам я не могу справиться лучше, чем Саттер и Александреску.
Я не занимаюсь C++, но разве нет настроек для современных IDE для применения стилей отступов или надстроек, которые выполняют такое украшение кода?
По возможности используйте пре-инкремент вместо пост-инкремента.
Начните писать много комментариев - но используйте это как возможность реорганизовать код, чтобы он не требовал пояснений.
то есть:
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()
}
Я использую PC-Lint в своих проектах на C++, и мне особенно нравится, как он ссылается на существующие публикации, такие как рекомендации MISRA или «Эффективный C++» и «Более эффективный C++» Скотта Мейерса. Даже если вы планируете написать очень подробное обоснование для каждого правила, которое проверяет ваш инструмент статического анализа, рекомендуется указать на установленные публикации, которым доверяет ваш пользователь.
Вот самый важный совет, который мне дал гуру C++, и он помог мне в нескольких критических случаях найти ошибки в моем коде:
С помощью этих двух правил компилятор бесплатно сообщит вам, где в вашем коде есть ошибки!
Интеллектуальные указатели позволяют очень четко обозначать право собственности. Если вы класс или функция:
Я нахожу аргументы в пользу auto_ptr особенно сильными: в дизайне, если я вижу auto_ptr, я сразу понимаю, что этот объект собирается «блуждать» из одной части системы в другую.
По крайней мере, это та логика, которую я использую в своем любимом проекте. Я не уверен, сколько вариантов может быть по этой теме, но до сих пор этот набор правил мне хорошо служил.
Кроме того, для некоторых хороших методов вы можете следовать Блог Google "Тестирование в туалете".
Посмотри на это через полгода
Я согласен с тем, что установка константы слева защищает от отсутствующего знака = ... но мне так и не удалось ее перенять. Код просто читается более естественно, наоборот. К счастью, у большинства компиляторов есть настройка, предупреждающая о конструкциях «if (a = b)».