Possible Duplicate:
Downcasting using the Static_cast in C++
I'm very confused by when do we need to convert pointer to base object into pointer of derived class? Can anyone do me a favor to give me some example?
Possible Duplicate:
Downcasting using the Static_cast in C++
I'm very confused by when do we need to convert pointer to base object into pointer of derived class? Can anyone do me a favor to give me some example?
What kind of conversion are you talking about?
If it's about down casting (or dynamic casting, which is the same kind but it's verified at runtime) then you are allowed to do it to force the type checker to not check that specific type by enforcing the one you are specifying.
This means that it is a potential break inside your code, the guaranteed type safety is missing in that specific instruction but sometimes it is needed, even if a good design should never need it a priori.
The necessity is given by the fact that without the cast you wouldn't be allowed to call any method of the derived class even if you are sure that the pointer to the base one contains a derived one (but the compiler can't verify it).
WHEN
so heres an example:
say you have a factory (an animal factory) that you can send it a string or an enum of what type of object you want...
"Hey Animal Factory, give me a 'Dog'"
there are two ways to write your factory...
You could write a function for every animal like so (good programmers dont do this):
or you could write a factory with one function like so (dont think about generics for now):
You know that Animal is actually a dog or cat so you can typecast it to what you need it to be WHEN you need to access the members of Dog or Cat...
My Favorite thing to do in C++ is the temporary cast to get into something (excuse my C++ its rusty)
Animal* myAnimal = Factory.GetAnimal("Dog");
int barkVolume = ((Dog*)myAnimal).BarkVolume;
Imagine you have a base class Animal
and two derived classes, Cat
and Dog
.
// Assume methods are public.
class Animal { virtual void Attack(); }
class Dog : public Animal { void Meow(); }
class Cat : public Animal { void Bark(); }
We can use base class pointers to reference our derived objects. This helps as we can now contain them as the same type.
Animal* myCat = new Cat;
Animal* myDog = newDog;
std::vector<Animal*> myAnimals;
myAnimals.push_back(myCat);
myAnimals.push_back(myDog);
This is useful, as we can call base member functions all all kinds of animals, regardless of their derived class types.
// Call Attack() on every cat and dog.
for_each(myAnimals.begin(), myAnimals.end(), [](auto& e) { e->Attack(); });
You can use dynamic casting to test if one of the base pointers can be converted into a derived class pointer.
Cat* realCat = dynamic_cast<Cat*> myAnimals[0]; // Success. Pointer is valid.
Cat* fakeCat = dynamic_cast<Cat*> myAnimals[1]; // Failure, it's not a cat. NULL.
You can now call your member methods, such as Meow()
from the derived class pointers. This was not possible before, as Animal
does not have these methods.
realCat->Meow(); // Valid.
myCat->Meow(); // Animal*, there is not Meow() method.
You would need to do this to access members of the derived class that don't exist in the base class. With good programming practices and generics, you probably shouldn't have pointers typed as the base class anyway, though.