5 Осторожно union-ы

      Комментарии к записи 5 Осторожно union-ы отключены

Помечено: ,

В этой теме 0 ответов, 1 участник, последнее обновление  Васильев Владимир Сергеевич 2 мес., 2 нед. назад.

  • Автор
    Сообщения
  • #3576

    Осторожно, union-ы!

    В языке C++ существует ряд очень неприятных и небезопасных элементов. Часть из них является наследством от языка C, часть является грамматикой непосредственно C++. Так или иначе — будьте особенно бдительны при работе с нижеследующим. union-ы не пью!

    Простые указатели

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

    Неперегруженный оператор получения адреса

    Практически всегда можно обойтись без простых указателей. Исключением является общение с внешним 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.

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

Для ответа в этой теме необходимо авторизоваться.