(например, new
) в отдельной инструкции, которая тут же передает ресурс управляющему объекту (например, shared_ptr
), например:
shared_ptr<Widget> sp1(new widget), sp2(new Widget);
Fun(sp1, sp2);
См. также описание дополнительных преимуществ такого стиля в рекомендации 31.
Можно чересчур увлечься интеллектуальными указателями. Обычные указатели вполне подходят для кода, в котором указываемый объект виден только в ограниченном объеме (например, внутри класса — типа указателя на узел дерева в классе Tree
, использующийся для навигации по дереву).
Стиль кодирования
Константа для одного является переменной для другого.
В этом разделе мы перейдем от вопросов проектирования к вопросам, которые появляются в основном при реальном кодировании.
Правила и рекомендации из этого раздела применимы безотносительно к конкретной области языка программирования (например, функциям, классам или пространствам имен), но приводят к повышению качества вашего кода. Многие из представленных идиом позволяют вашему компилятору активнее помогать вам в работе, а вам — избежать опасных мест (включая неопределенное поведение), которые компилятор не всегда в состоянии выявить. Все это делает ваш код более надежным.
В этом разделе мы считаем наиболее важной рекомендацию 14: 'Предпочитайте ошибки компиляции и компоновки ошибкам времени выполнения'.
14. Предпочитайте ошибки компиляции и компоновки ошибкам времени выполнения
Не стоит откладывать до выполнения программы выявление ошибок, которые можно обнаружить при ее сборке. Предпочтительно писать код, который использует компилятор для проверки инвариантов в процессе компиляции, вместо того, чтобы проверять их во время работы программы. Проверки времени выполнения зависят от выполнимого кода и данных, так что вы только изредка можете полностью полагаться на них. Проверки времени компиляции, напротив, не зависят от данных и предыстории исполнения, что обычно обеспечивает более высокую степень надежности.
Язык С++ предлагает массу средств для 'ускорения' обнаружения ошибок во время компиляции. Использование этих возможностей статических проверок дает массу преимуществ, включая следующие.
•
•
•
Один из наиболее мощных инструментов статических проверок в С++ — статическая проверка типов. Споры о том, должны ли типы проверяться статически (С++, Java, ML, Haskell) или динамически (Smalltalk, Ruby, Python, Lisp), все еще активно продолжаются. В общем случае нет явного победителя, и имеются языки и стили разработки, которые дают хорошие результаты как в одном, так и во втором случае. Сторонники статической проверки аргументируют свою позицию тем, что обработка большого класса ошибок времени выполнения может быть просто устранена, что дает более надежную и качественную программу. Поклонники динамических проверок говорят, что компиляторы способны выявить только часть потенциальных ошибок, так что если вы все равно должны писать тесты для ваших модулей, вы можете вообще не волноваться о статических проверках, получив при этом менее ограничивающую среду программирования.
Понятно одно: в контексте статически типизированного языка С++, обеспечивающего строгую проверку типов и минимальную автоматическую проверку времени выполнения, программисты определенно должны использовать систему типов для своей пользы везде, где только это возможно (см. рекомендации с 90 по 100). В то же время тестирование времени выполнения целесообразно для выполнения проверок, зависящих от данных и потока выполнения программы (например, проверка выхода за границы массива или корректности входных данных) (см. рекомендации 70 и 71).
Имеется ряд примеров, где вы можете заменить проверки времени выполнения проверками времени компиляции.
sizeof(int) >= 8
, используйте статические проверки (обратите также внимание на рекомендацию 91).
dynamic_cast
(или, что еще хуже, непроверяемый static_cast
) для понижающего преобразования типов, возможно, ваш базовый класс предоставляет слишком малую функциональность? Подумайте над перепроектированием ваших интерфейсов таким образом, чтобы ваша программа могла выразить необходимые вычисления посредством базового класса.