Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is Nokia mis-using static_cast?

I've just came across this example:

Scroll down to the bottom of the page, where you will find

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

Parent is of type: QObject, which is the Base class of QWidget, so in this case, isnt: dynamic_cast should be used?

such as:

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

Thanks,

like image 606
snoofkin Avatar asked Mar 28 '11 14:03

snoofkin


3 Answers

If you know that you are down-casting from a base to a descendant class (i.e., you know the object is actually an instance of the descendant class), then static_cast is perfectly legal (and more performant).

like image 191
Jollymorphic Avatar answered Nov 11 '22 14:11

Jollymorphic


Nope, if parent has run time type QWidget*, then static_cast<QWidget*>(parent) is well defined, and does what you expect. If it has not, then behaviour is undefined.

Contrast with dynamic_cast, which has always defined behaviour but which is less efficient, since it has to use run time type information.

A good way to downcast safely in debug mode and quickly in release mode is for instance:

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
}

used like this:

QWidget* w = down_cast<QWidget*>(parent);
like image 45
Alexandre C. Avatar answered Nov 11 '22 15:11

Alexandre C.


Since you’re explicitly asking for mis-use: the opposite is true, it would be a mis-use to have dynamic_cast here.

While both are legal, dynamic_cast indicates that you (the programmer) are not sure that the cast will succeed, and it is expected that you check the result of the cast to test for success. When you are sure that a cast will succeed, then this is highly misleading. Hence, use a static_cast instead. This indicates that the types are always well-known and that the result of the cast is sure to succeed.

like image 2
Konrad Rudolph Avatar answered Nov 11 '22 14:11

Konrad Rudolph