问题
dynamic_cast
is generally used when we have a base class pointer and want to downcast it to a derived class. For instance,
class A
{
public:
virtual void foo();
};
class B : public A
{
public:
void foo();
};
main()
{
A* a = new B();
B* b = dynamic_cast<B*> (a);
}
But, the same can also be accomplised by using C-style
cast:
B* b = (B*)a;
So, my question is what are the circumstances/cases where it becomes completely necessary to use this operator i.e. there is no other choice?
回答1:
When you don't actually know that a
points to object of type B
dynamic_cast
will return a null pointer, which you can check and handle the situation accordingly. With C-style cast you get a pointer, but when you try to use it undefined behavior happens.
回答2:
But, the same can also be accomplised by using C-style cast:
No, it cannot :)
By definition, The C-Style cast will try to perform a series of const_cast
, static_cast
, and reinterpret_cast
1 to achieve your desired cast but not dynamic_cast
. So, essentially, here C-style cast is equivalent to a static_cast
which will have undefined behavior if the actual dynamic types won't match (conversely, in this situation the dynamic cast will return nullptr
in case of pointers and throw std::bad_cast
in case of references).
That is to say, if you're certain that you're casting to the right type, then use static_cast
(or C-style cast, but I personaly don't like it). But if you are not certain, then use dynamic_cast
1 C-Style cast can be used to also cast to a private base, which can't be done with the aforementioned series of C++-Style casts
回答3:
If your question is when you should use dynamic_cast over C-style cast, the answer is always (that is, if you have to choose between C-style cast and dynamic_cast, always prefer dynamic_cast).
In general though, strive to never use C-style casts in C++. They are difficult to locate by a tool (unless that tool is a compiler) and they lead to code that has to be read explicitly looking for casts whenever you refactor (sources of bugs).
If your question is when you should use dynamic_cast over designs that do not require it, the answer is almost never. Generally, you should avoid designs that require your implementation to downcast pointers or references. When your implementation forces you to down-cast, it is most often a sign of poor design (i.e. the correct solution is probably refactoring, not down-casting).
回答4:
Adding to some of the answers above, even if you ignore the fact dynamic_cast
is clever, using c style casts in c++ code as a replacement for static
/const
/reinterpret
cast is really dangerous.
Depending on what is visible at the time of the cast [which can change if header files get removed for example], a c-style cast may not do pointer arithmetic correctly and leave you ending up with a garbage pointer.
You never want adding or removing header files to change the meaning of your code. C++ casts do not have this problem, if the compiler cannot work out what it should do you'll get a compilation failure, and not the random runtime crashes you may get with c style casts.
回答5:
One situation in which a dynamic_cast returns a different (and correct) result is when you’re casting from a non-leftmost base class:
class A {
public:
int x;
}
class B {
public:
virtual void foo();
};
class C : public A, public B
{
public:
void foo();
};
main()
{
B* b = new C();
C* c = dynamic_cast<C*>(b);
}
A C-style cast would return an incorrect pointer here.
来源:https://stackoverflow.com/questions/17597859/forced-necessity-of-dynamic-cast-operator-in-c