问题
Scott Meyer
in his book Effective C++
says dynamic_cast
is used to perform safe casts down or across an inheritance hierarchy. That is, you use dynamic_cast to cast pointers or references to base class objects into pointers or references to derived or sibling base class objects in such a way that you can determine whether the casts succeeded.
Failed casts are indicated by a null pointer (when casting pointers) or an exception (when casting references).
I would like to get two code snippet showing the failed cast in the case of casting pointer and casting reference can be indicated.
回答1:
For pointers, it's a simple null check:
A* a = new A();
B* b = dynamic_cast<B*>(a);
if (b == NULL)
{
// Cast failed
}
For references, you can catch:
try {
SomeType &item = dynamic_cast<SomeType&>(obj);
}
catch(const std::bad_cast& e) {
// Cast failed
}
回答2:
Here's a complete example that shows how dynamic_cast
can fail to produce a pointer.
class A
{
public:
virtual void Foo();
};
class B: public A
{
};
class C: public A
{
};
void test()
{
A a;
B b;
A* pA = &b;
B* pB = dynamic_cast<B*>(pA); // this works OK, returns the expected pointer
C* pC = dynamic_cast<C*>(pA); // this returns NULL because B isn't a C
}
In the real world you'll be trying to cast pointers that weren't so straightforwardly created, perhaps they come from a vector
for example.
回答3:
Based on the OP's comment (" I do not understand how casts could fail as mentioned by Scott."), the real question here is really something like: "how could a dynamic_cast
fail?"
The time it would fail is when the target type does not match the dynamic type of the object. For a simple example:
struct A {
virtual ~A() {}
};
class B : public A {};
int main() {
A *a = new A;
B *b = dynamic_cast<B *>(a); // should fail
if (b == NULL)
std::cout << "First cast failed.\n";
A *c = new B;
b = dynamic_cast<B *>(c); // should succeed
if (b == NULL)
std::cout << "Second cast failed.\n";
return 0;
}
Here although a
could point to an object of type B
, it actually does point to an object of type A
. When we try to do a dynamic_cast to get it to point to a B
, that fails. In the second attempt, we again have a pointer that not only could but does point to an object of type B
. Since it does, the dynamic_cast to B *
succeeds in this case.
The basic situation doesn't change (much) for the reference case, just a
, b
and c
become references instead of pointers, and we note the failure by catching an exception (which @ReedCopsey has already demonstrated well enough that I don't think I have anything new to add).
来源:https://stackoverflow.com/questions/11510128/how-to-identify-failed-casts-using-dynamic-cast-operator