93. Избегайте применения static_cast к указателям
93. Избегайте применения static_cast к указателям
Резюме
К указателям на динамические объекты не следует применять преобразование static_cast. Используйте безопасные альтернативы — от dynamic_cast до перепроектирования.
Обсуждение
Подумайте о замене static_cast более мощным оператором dynamic_cast, и вам не придется запоминать, в каких случаях применение static_cast безопасно, а в каких — чревато неприятностями. Хотя dynamic_cast может оказаться немного менее эффективным преобразованием, его применение позволяет обнаружить неверные преобразования типов (но не забывайте о рекомендации 8). Использование static_cast вместо dynamic_cast напоминает экономию на ночном освещении, когда выигрыш доллара в год оборачивается переломанными ногами.
При проектировании постарайтесь избегать понижающего приведения. Перепроектируйте ваш код таким образом, чтобы такое приведение стало излишним. Если вы видите, что передаете в функцию базовый класс там, где в действительности потребуется производный класс, проследите всю цепочку вызовов, чтобы понять, где же оказалась потерянной информация о типе; зачастую изменение пары прототипов оказывается замечательным решением, которое к тому же делает код более простым и понятным.
Чрезмерное применение понижающего приведения может служить признаком слишком бедного интерфейса базового класса. Такой интерфейс может привести к тому, что большая функциональность определяется в производных классах, и всякий раз при необходимости расширения интерфейса приходится использовать понижающее приведение. Одно из решений данной проблемы — перепроектирование базового интерфейса в целях повышения функциональности.
Тогда и только тогда, когда становятся существенны накладные расходы, вызванные применением dynamic_cast (см. рекомендацию 8), следует подумать о разработке собственного преобразования типов, который использует dynamic_cast при отладке и static_cast в окончательной версии (см. [Stroustrup00]):
template<class To, class From> To checked_cast(From* from) {
assert(dynamic_cast<To>(from) ==
static_cast<To>(from) && "checked_cast failed" );
return static_cast<To>(from);
}
template<class To, class From> To checked_cast(From& from) {
typedef tr1::remove_reference<To>::type* ToPtr; // [C++TR104]
assert(dynamic_cast<ToPtr>(&from) ==
static_cast<ToPtr>(&from) && "checked_cast failed");
return static_cast<To>(from);
}
Эта пара функций (по одной для указателей и ссылок) просто проверяет согласованность двух вариантов преобразования. Вы можете либо самостоятельно приспособить checked_cast для своих нужд, либо использовать имеющийся в библиотеке.
Ссылки
[Dewhurst03] §29, §35, §41 • [Meyers97] §39 • [Stroustrup00] §13.6.2 • [Sutter00] §44
Более 800 000 книг и аудиокниг! 📚
Получи 2 месяца Литрес Подписки в подарок и наслаждайся неограниченным чтением
ПОЛУЧИТЬ ПОДАРОКЧитайте также
Избегайте слов «продолжить», «назад» и «применить»
Избегайте слов «продолжить», «назад» и «применить» Слова «продолжить», «назад», «применить» и другие являются неоднозначными и могут запутать потенциального клиента.При виде них часто возникают вопросы:• Что продолжить – делать покупки или процесс оплаты?• Куда
Избегайте повторного ввода данных
Избегайте повторного ввода данных Если пользователь уже сообщил вам что-то о себе (например, имя), лучше запомнить эту информацию и не спрашивать ее повторно, например при последующей регистрации.Лучше самим заботливо вписать имя в соответствующее поле. Людей раздражает,
16. Избегайте макросов
16. Избегайте макросов РезюмеМакрос — самый неприятный инструмент С и С++, оборотень, скрывающийся под личиной функции, кот, гуляющий сам по себе и не обращающий никакого внимания на границы ваших областей видимости. Берегитесь его!ОбсуждениеТрудно найти язык, достаточно
17. Избегайте магических чисел
17. Избегайте магических чисел РезюмеИзбегайте использования в коде литеральных констант наподобие 42 или 3.1415926. Такие константы не самоочевидны и усложняют сопровождение кода, поскольку вносят в него трудноопределимый вид дублирования. Используйте вместо них
20. Избегайте длинных функций и глубокой вложенности
20. Избегайте длинных функций и глубокой вложенности РезюмеКраткость — сестра таланта. Чересчур длинные функции и чрезмерно вложенные блоки кода зачастую препятствуют реализации принципа "одна функция — одна задача" (см. рекомендацию 5), и обычно эта проблема решается
30. Избегайте перегрузки && , || и , (запятой)
30. Избегайте перегрузки &&, || и , (запятой) РезюмеМудрость — это знание того, когда надо воздержаться. Встроенные операторы &&, || и , (запятая) трактуются компилятором специальным образом. После перегрузки они становятся обычными функциями с весьма отличной
75. Избегайте спецификаций исключений
75. Избегайте спецификаций исключений РезюмеНе пишите спецификаций исключений у ваших функций, если только вас не заставляют это делать внешние обстоятельства (например, код, который вы не можете изменить, уже ввел их; см. исключения к данному разделу).ОбсуждениеЕсли
92. Избегайте reinterpret_cast
92. Избегайте reinterpret_cast РезюмеКак гласит римская пословица, у лжи короткие ноги. Не пытайтесь использовать reinterpret_cast, чтобы заставить компилятор рассматривать биты объекта одного типа как биты объекта другого типа. Такое действие противоречит безопасности
94. Избегайте преобразований, отменяющих const
94. Избегайте преобразований, отменяющих const РезюмеПреобразование типов, отменяющее const, может привести к неопределенному поведению, а кроме того, это свидетельство плохого стиля программирования даже в том случае, когда применение такого преобразования вполне
Совет 18. Избегайте vector<bool>
Совет 18. Избегайте vector<bool> Vector<bool> как контейнер STL обладает лишь двумя недостатками. Во-первых, это вообще не контейнер STL. Во-вторых, он не содержит bool.Объект не становится контейнером STL только потому, что кто-то назвал его таковым — он становится контейнером STL лишь
Совет 47. Избегайте «нечитаемого» кода
Совет 47. Избегайте «нечитаемого» кода Допустим, имеется вектор vector<int>. Из этого вектора требуется удалить все элементы, значение которых меньше х, но оставить элементы, предшествующие последнему вхождению значения, не меньшего у. В голову мгновенно приходит следующее
Избегайте использовать goto
Избегайте использовать goto В принципе вы никогда не обязаны пользоваться оператором goto при программировании на Си. Но если ваш предыдущий опыт связан с работой на Фортране или Бейсике, в каждом из которых требуется его использовать, то у вас могли выработаться навыки
Избегайте настроек
Избегайте настроек Примите решение о деталяхВы сталкиваетесь с ограничением: сколько сообщений должно быть на странице? Ваша первая мысль сделать выбор 25, 50 или 100. Это легкий выход. Просто примите решение, как сделать лучше. И выберите одно число.Настройки — уход от пути