Nokia неправильно использует static_cast? - PullRequest
6 голосов
/ 28 марта 2011

Я только что натолкнулся на этот пример :

Прокрутите вниз до нижней части страницы, где вы найдете

QWidget *pw = static_cast<QWidget *>(parent);

Родитель имеет тип: QObject, который является базовым классом QWidget, поэтому в этом случае isnt: dynamic_cast следует использовать?

, например:

QWidget *pw = dynamic_cast<QWidget*>(parent)

Спасибо,

Ответы [ 6 ]

8 голосов
/ 28 марта 2011

Нет, если parent имеет тип времени выполнения QWidget*, то static_cast<QWidget*>(parent) четко определено и выполняет то, что вы ожидаете. Если нет, то поведение не определено.

Контрастность с dynamic_cast, которая всегда определяла поведение, но менее эффективна, поскольку должна использовать информацию о типе времени выполнения.

Хороший способ безопасно снизить версию в режиме отладки и быстро в режиме выпуска, например:

template <typename T, typename U>
T* down_cast(U* x)
{
#ifdef NDEBUG
    return static_cast<T*>(x);
#else
    return &dynamic_cast<T&>(*x); // Thanks @Martin
#endif
}

используется так:

QWidget* w = down_cast<QWidget*>(parent);
8 голосов
/ 28 марта 2011

Если вы знаете, что вы преобразуетесь из базового класса в класс-потомок (т. Е. Вы знаете, что объект на самом деле является экземпляром класса-потомка), то static_cast является совершенно допустимым (и более производительным).

2 голосов
/ 28 марта 2011

Поскольку вы явно просите о неправильном использовании: верно и обратное, было бы неправильным использовать dynamic_cast здесь.

Хотя оба они допустимы, dynamic_cast означает, что вы(программист) не уверен, что приведение будет успешным, и ожидается, что вы проверили результат приведения для проверки на успешность.Когда вы уверены, что приведение будет успешным, это очень вводит в заблуждение.Следовательно, вместо этого используйте static_cast.Это указывает на то, что типы всегда хорошо известны и что результат приведения обязательно будет успешным.

0 голосов
/ 28 марта 2011

Обычно, но если ваш код может точно знать, что исходный объект является QWidget (возможно, через какой-то другой флаг), тогда вы можете сэкономить время и вместо этого сделать static_cast.Используйте с осторожностью.

0 голосов
/ 28 марта 2011

Здесь нет «должно быть». Оба будут отлично работать. Причина использования dynamic_cast здесь может быть, если вы хотите выполнить проверку правильности преобразования во время выполнения. Но автор кода не чувствовал, что им нужна проверка во время выполнения, поэтому в dynamic_cast не было необходимости.

На самом деле, dynamic_cast редко требуется, потому что в большинстве случаев static_cast выполнит эту работу. Подобно тому, как проверка работоспособности могла бы добавить утверждение с dynamic_cast, но не как основной метод приведения.

0 голосов
/ 28 марта 2011

До тех пор, пока вы можете убедиться, что родительский объект действительно должен быть QWidget или производным типом QWidget, static_cast в порядке и дает вам дополнительную информацию, которую вы потеряете с dynamic_cast.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...