10 Способов избежать ошибок в C ++

10 Способов избежать ошибок на C ++ - манекены

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

Включить все предупреждения и сообщения об ошибках

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

Однако, когда C ++ сталкивается с структурой, которую он может вычислить, но структура все равно пахнет рыбной ситуацией, C ++ генерирует предупреждающее сообщение. Поскольку C ++ уверен, что он понимает, что вы хотите, он идет вперед и создает исполняемый файл, чтобы вы могли игнорировать предупреждения, если хотите. На самом деле, если вы действительно не хотите, чтобы вас беспокоили, вы можете отключить предупреждения.

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

Принять четкий и последовательный стиль кодирования

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

Когда вы читаете код, который является чистым и аккуратным и который следует стилю, с которым вы знакомы, вы проводите очень мало мозговой силы, анализируя синтаксис операторов C ++. Это оставляет больше возможностей процессора процессора для декодирования того, что программа пытается сделать, а не того, как это делается.

Хороший стиль кодирования позволяет вам сделать следующее с легкостью:

  • Различать имена классов, имена объектов и имена функций

  • Понять, что класс, функция или объект используются для , основанный на его имени

  • Различать символы препроцессора из символов C ++ (то есть, объекты #define должны выделяться)

  • Определить блоки кода C ++ на одном уровне (это результат согласованного отступа)

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

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

Комментировать код во время его написания

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

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

Один шаг по каждому пути в отладчике по крайней мере один раз

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

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

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

Ограничить видимость

Ограничение видимости внутренних элементов класса во внешнем мире является краеугольным камнем объектно-ориентированного программирования. Класс должен нести ответственность за свое внутреннее состояние - если в классе что-то закручивается, то это ошибка программиста класса. Программист-программист должен заботиться о решении проблемы.

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

Следить за памятью кучи

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

Как правило, программисты должны всегда выделять и освобождать память кучи на одном уровне. «Если функция-член MyClass:: create () выделяет блок памяти кучи и возвращает его вызывающему, тогда должен быть член MyClass:: release (), который возвращает его в кучу.В частности, MyClass:: create () не требует, чтобы родительская функция освобождала память.

Если это вообще возможно, MyClass должен следить за такими указателями памяти самостоятельно и удалять их в деструкторе.

Нулевые указатели после удаления того, что они указывают на

Убедитесь, что вы указали нулевые указатели после того, как они больше не действительны; вы делаете это, назначая им значение nullptr. Причины этого действия становятся ясными с опытом: вы можете продолжать использовать блок памяти, который был возвращен в кучу и даже не знает об этом. Программа может работать нормально в 99% случаев, что затрудняет поиск 1% случаев, когда блок перераспределяется, и программа не работает.

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

Использовать исключения для обработки ошибок

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

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

Объявить деструкторы virtual

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

«Но, - говорите вы, - мой класс не наследует ни от чего, и он не подклассифицирован другим классом. «Да, но может стать базовым классом в будущем. Если у вас нет веских оснований не объявлять виртуальный деструктор, тогда сделайте это, когда вы сначала создадите класс.

Предоставить конструктор копирования и перегруженный оператор присваивания

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

Когда вызывается деструктор для одного из этих объектов, он восстанавливает активы. Когда деструктор для другого экземпляра приходит, он все испортит.