简体   繁体   中英

What are the reasons upcasting and downcasting are used in C++?

I read the description about upcasting and downcasting from http://www.studytonight.com/cpp/upcasting.php :

[...] the act of converting a Sub class's reference or pointer into its Super class's reference or pointer is called Upcasting. The opposite of Upcasting is Downcasting, in which we convert Super class's reference or pointer into derived class's reference or pointer. We will study more about Downcasting later.

But I do not understand why upcasting and downcasting are used in C++. Can you give an explanation about why these mechanisms are used?

The main reason for the usage of them is to make polymorphism possible. Another technique that is needed for polymorphism is late/dynamic binding .

Upcasting allows us to use inherited classes (sub-classes) with the base class interface. You can handle those object with the same base class interface without need to know what concrete child class object it is.
On the other hand, downcasting is needed because you may want to get the special methods or member variables of a child object. Then, you need to downcast.
To cast up or down you can safely use the dynamic_cast which is described here .

If the cast is successful, dynamic_cast returns a value of type new_type. If the cast fails and new_type is a pointer type, it returns a null pointer of that type. If the cast fails and new_type is a reference type, it throws an exception that matches a handler of type std::bad_cast .

To up or downcast between base and child class you need either a pointer ( type* ) or a reference type ( type& ) because only the view to the object changes not the concrete object itself. If you use the object itself object slicing would occur and you would lose information of an inherited class.


I give you one example when to use up- and downcasting. Consider you have a parent class Car and 2 classes Porsche and Ford that are inherited from Car . Now you have a std::vector<Car*> cars for example where you want to put in different cars. You would do something like:

std::vector<Car*> cars;
cars.push_back(new Porsche()); /* implicit upcast */
cars.push_back(new Ford());    /* implicit upcast */

The benefit is you have one vector of "different" objects, it's possible because both have the same parent class.

If you now want to get those cars you can do:

Car*     porscheAsCar = cars.at(0);
Porsche* porsche      = dynamic_cast<Porsche*>(cars.at(0));

Now for example the Car class does have a drive() method and the Porsche class a driveFast() method implemented. You would access them:

porscheAsCar->drive(); /* Call Porsche drive() method     */
porsche->drive();      /* Call Porsche drive() method     */
porsche->driveFast();  /* Call Porsche driveFast() method */

Even though we call the drive method with the base class interface it will be the drive method of the Porsche , if the method is declared with virtual . With the downcast you can access the methods/member variables that are specific for the inherited class. But it is just possible if the Car is really a Porsche and not a Ford for example.

Full example with some output on ideone see here .

When have a base class, from which several classes inherit, we often want a pointer that can point to one of those derived classes.

For example we can have an Animal class and derived Dog and Cat classes:

class Animal {};

class Dog : public Animal {};
class Cat : public Animal {};

Dog dog;
Animal* a = &dog;

Cat cat;
Animal* b = &cat;

Often times, we want to have a pointer that can pointer to one of these objects. We can use an Animal pointer, since both a Dog and a Cat are a type of Animal. This is the nature of upcast. We upcast a derived class and represent it as the base class.

What about downcasting? We can do so using a dynamic_cast:

Cat c;
Animal* animal = &c; //Implicit upcast
Cat* cat = dynamic_cast<Cat*>(animal); //Explicit downcast
//Check if dynamic cast worked:
if(!cat) {
    //ERROR: Not a cat object
}

In my humble opinion, the website you are using is of a poor quality. I've tried to read some article: they are not incorrect but they are not even suitable for who is trying to enter in the C++ world with a little programming experience. Even I, with my little 15 years experience as professional C++ programmer, found it a little bit stressful to read.

As someone said a good book, even free, it's a better solution. Google is your best friend for search. That's a good answer to your question, more complete than whatever I could write:https://www.tutorialcup.com/cplusplus/upcasting-downcasting.htm

Have a nice day, Ste.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM