| 6. Осторожно, union-ы! | |
| В языке C++ существует ряд очень неприятных и небезопасных элементов. Часть из них является наследством от языка C, часть является грамматикой непосредственно C++. Так или иначе — будьте особенно бдительны при работе с нижеследующим. |  |
| | |
| Простые указатели | |
| Используйте смарт-поинтеры вместо простых указателей — пусть за освобождением ресурсов следит компилятор. Одно из немногих исключений — указатели иногда бывают удобны для манипуляции статическими процессами. | |
| | |
| Неперегруженный оператор получения адреса | |
| Практически всегда можно обойтись без простых указателей. Исключением является общение с внешним API и, быть может, еще несколько специфических ситуаций. | |
| | |
| Неперегруженный оператор «квадратные скобки» | |
| Не используйте обычные массивы. Пользуйтесь STL- и boost-контейнерами. STL-совместимый контейнер — наиболее естественное с точки зрения языка хранилище данных. | |
| | |
| union | |
| Не обманывайте компилятор. Поверьте, если компилятор решил, что типы не могут быть преобразованы друг в друга, то на это у него есть весьма веские причины. Старайтесь даже в самых крайних ситуациях ограничиться использованием static_cast. | |
| | |
| Ellipsis-функции | |
| У ellipsis-функций есть всего один недостаток — это механизм времени выполнения, а не времени компиляции. Пользуйтесь потоками. В отличие от функций с произвольным числом аргументов, проверка соответствия типов и вычисления размера стека для потоков произойдет на этапе компиляции. | |
| | |
| const_cast | |
| Необходимость в отмене константности практически всегда говорит о том, что где-то когда-то на каком-то этапе, либо в вашем коде, либо в коде, которым вы пользуетесь, произошла ошибка. Лучше всего сделать локальную неконстантную копию объекта, и пользоваться уже им. Если же это невозможно (например, объект не является CopyConstructable), то все равно… еще пять раз подумайте, прежде чем отменить константность. В общем случае отмена константности это undefined behaviour. | |
| | |
| reinterpret_cast | |
| Не делайте никаких предположений о размере, значении и порядке байт в указателе. reinterpret_cast это завязка на одно из таких предположений. Одно из очень немногих мест, где данный оператор имеет право на существование, это код, привязанный к какой-то конкретной платформе используемым API. Как вариант — платформно-зависимые реализации, скрытые за «pimpl». | |
| | |
| dynamic_cast | |
| Необходимость в downcast-е чаще всего говорит о том, что система плохо спроектирована. Необходимость в информации о наследнике практически всегда говорит о том, что абстрактный интерфейс не покрывает всех его потребностей. | |
| | |
| C-style cast | |
| C-style cast это один из самых больших ахтунгов, доставшихся от языка C. C-style cast ложил болт на всю статическую типизацию, которую так догло и упорно разрабатывали комитетчики. Трудно сказать, существуют ли в C++ ситуации, в которых C-style cast был бы наиболее подходящим решением. | |
| | |
| Приведение вниз по иерархии классов | |
| Комментарии те же, что и относительно dynamic_cast. Однако, в редких случаях приведение вниз по иерархии классов вполне допустимо. Речь идет о случаях, когда вы точно знаете, что приведение не может быть ошибочным. Один из таких случаев — «Curiously recurring template pattern». | |
| | |
| RTTI | |
| Желание иметь информацию о типах на этапе выполнения идет в разрез с идеей статической типизации. Одни из редких случаев, когда RTTI вроде бы себя оправдывает (помимо dynamic_cast), это сериализация в human-readable формат, а также некоторые отладочные инструменты. Кроме того, имейте в виду, что Стандарт не предъявляет каких либо требований к форматированию результата typeid::name. | |
| | |
| Приведенный список, конечно же, не является списком стопроцентных проблем. Жизнь довольно разнообразна и непредсказуема, и для каждого из перечисленных элементов вероятнее всего найдется ситуация, когда он будет являться наиболее разумным (или даже единственным) решением. Однако, в подавляющем большинстве случаев существуют более разумные решения. Поэтому, если у вас возникла необходимость воспользоваться чем-либо из приведенного списка, скорее всего вы где-то ошиблись. Пользуйтесь перечисленными инструментами только в самых крайних ситуациях. | |