Обозначение кодировки «UTF-16» всегда будет кодироваться с помощью спецификации и декодировать данные с использованием либо большой / маленькой сущности, но «UnicodeBig» и «UnicodeLittle» полезны для кодирования в определенном порядке байтов. Используйте UTF-16LE или UTF-16BE без спецификации - см. Этот пост о том, как использовать «\ uFEFF» для ручной обработки спецификаций. См. здесь для канонического именования символов строки кодировки или (предпочтительно) класса Charset . Также обратите внимание, что для поддержки требуется только ограниченное подмножество кодировок .
Если бы dynamic_cast
должен успешно выполняться, это была бы хорошая практика для использования boost::polymorphic_downcast
вместо этого, который идет немного что-то вроде этого:
assert(dynamic_cast<T*>(o) == static_cast<T*>(o));
return static_cast<T*>(o);
Таким образом, Вы обнаружите ошибки в отладочной сборке, одновременно избегая времени выполнения наверху в сборке конечных версий.
, Если Вы подозреваете, бросок мог бы сбой, и Вы хотите обнаружить его, использовать dynamic_cast
и бросить к ссылочному типу. Этот состав исполнителей бросит bad_cast
в случае ошибки и удалит Вашу программу. (Это хорошо, если, как Вы говорите, Вы не собираетесь восстанавливаться так или иначе)
T& t = dynamic_cast<T&>(o);
t.func(); //< Use t here, no extra check required
Использование dynamic_cast
к типу указателя, только если с 0 указателями имеет смысл в контексте. Вы могли бы хотеть использовать его в if
как это:
if (T* t = dynamic_cast<T*>(o)) {
t->func(); //< Use t here, it is valid
}
// consider having an else-clause
С этой последней опцией необходимо удостовериться, что путь выполнения имеет смысл если dynamic_cast
возвраты 0.
Для ответа на вопрос непосредственно: Я предпочел бы одну из двух первых альтернатив, которые я дал наличию явного assert
в коде:)
bad_cast только брошен при кастинге ссылок
dynamic_cast< Derived & >(baseclass)
, ПУСТОЙ УКАЗАТЕЛЬ возвращается при кастинге указателей
dynamic_cast< Derived * >(&baseclass)
, Таким образом, никогда нет потребности проверить обоих.
Утверждают, может быть приемлемым, но это значительно зависит от контекста, с другой стороны, это правда для в значительной степени каждого утверждать...
Я согласился бы с, 'это зависит' ответ, и также добавьте "Постепенное ухудшение": просто, потому что состав исполнителей перестал работать, где-нибудь не достаточно причины позволить сбою приложения (и пользователь теряют его работу, и т.д.). Я рекомендовал бы, чтобы комбинация утверждала и безопасное программирование:
ptr = dynamic_cast<MyClass>(obj);
ASSERT(ptr);
if(ptr)
{
// do stuff
}
Это зависит...;-)
, Если я действительно ожидал dynamic_cast
давать мне что-то применимое, например, если бы я и никто больше добавили полиморфный тип к контейнеру указателей на базовый класс, тогда я пошел бы со ссылочным броском и позволил бы эти std::bad_cast
, уничтожают мое приложение - не было бы очень еще, чтобы сделать, действительно.
Однако, если я запрашиваю полиморфный тип для некоторой возможности, представленной интерфейсом, который она должна не обязательно реализовать, тогда я пошел бы с броском указателя, и затем ПУСТОЙ УКАЗАТЕЛЬ не будет ошибкой (если, конечно, я не ожидал возможности к действительно быть там - но тогда я имел уведенный для ссылочного броска во-первых...)
Да и нет.
boost::polymorphic_downcast<>
, конечно, хороший вариант обработать ошибки dynamic_cast<>
во время фазы отладки. Однако стоит, чтобы упомянуть, что polymorphic_downcast<>
должен использоваться только, когда возможно предсказать, что полиморфный тип передал во время компиляции , иначе эти dynamic_cast<>
должен использоваться вместо него.
Однако последовательность:
if (T1* t1 = dynamic_cast<T1*>(o))
{ }
if (T2* t2 = dynamic_cast<T2*>(o))
{ }
if (T3* t3 = dynamic_cast<T3*>(o))
{ }
обозначает очень плохой дизайн, который должен быть, обосновываются [1 110] полиморфизм и виртуальные функции .