C Downcast to Interface Then Upcast Again
Upcasting and downcasting are an of import function of C++. Upcasting and downcasting give a possibility to build complicated programs with a simple syntax. It can be achieved past using Polymorphism.
C++ allows that a derived class arrow (or reference) to exist treated as a base form pointer. This is upcasting.
Downcasting is an opposite procedure, which consists of converting base form pointer (or reference) to derived class pointer.
C++ Upcasting and Downcasting should non be understood equally a simple casting of different information types. It can lead to great defoliation.
As you can see, Managing director and Clerk are both Employee. They are both Person too. What does information technology hateful? Information technology ways that Manager and Clerk classes inherit properties of Employee class, which inherits properties of Person class.
For example, we don't need to specify that both Manager and Clerk are identified by Start and Final name, have a bacon; you can show data virtually them and add a bonus to their salaries. We have to specify these properties only once in the Employee class:
At the same time, the Manager and Clerk classes are different. The Manager takes a commission fee for every contract, and the Clerk has data about his Managing director:
Try Information technology
#include <iostream> using namespace std; class Person { //content of Person }; class Employee:public Person { public: Employee(string fName, cord lName, double sal) { FirstName = fName; LastName = lName; bacon = sal; } string FirstName; string LastName; double salary; void show() { cout << "First Proper noun: " << FirstName << " Concluding Proper name: " << LastName << " Salary: " << salary<< endl; } void addBonus(double bonus) { salary += bonus; } }; form Manager :public Employee { public: Director(cord fName, string lName, double sal, double comm) :Employee(fName, lName, sal) { Commision = comm; } double Commision; double getComm() { return Commision; } }; class Clerk :public Employee { public: Clerk(cord fName, cord lName, double sal, Manager* human) :Employee(fName, lName, sal) { manager = man; } Director* director; Manager* getManager() { render director; } }; void congratulate(Employee* emp) { cout << "Happy Altogether!!!" << endl; emp->addBonus(200); emp->bear witness(); }; int main() { //pointer to base of operations class object Employee* emp; //object of derived form Manager m1("Steve", "Kent", 3000, 0.2); Clerk c1("Kevin","Jones", k, &m1); //implicit upcasting emp = &m1; //It's ok cout<<emp->FirstName<<endl; cout<<emp->bacon<<endl; //Fails because upcasting is used //cout<<emp->getComm(); congratulate(&c1); congratulate(&m1); cout<<"Manager of "<<c1.FirstName<<" is "<<c1.getManager()->FirstName; }
Manager and Clerk are always Employees. Moreover, Employee is a Person. Therefore, the Manager and Clerk are Persons as well. You have to sympathize information technology before we start learning upcasting and downcasting.
Both upcasting and downcasting practise not change the object by itself. When y'all utilise upcasting or downcasting you only "label" an object in unlike ways.
UPCASTING
Upcasting is a process of creating a pointer or a reference of the derived course object as a base class pointer. You do not demand to upcast manually. Y'all just need to assign derived class arrow (or reference) to base class pointer:
//pointer to base form object Employee* emp; //object of derived class Manager m1("Steve", "Kent", 3000, 0.2); //implicit upcasting emp = &m1;
When you use upcasting, the object is not changing. Notwithstanding, when you upcast an object, y'all will be able to admission merely member functions and information members that are defined in the base class:
//It's ok emp->FirstName; emp->bacon; //Fails because upcasting is used emp->getComm();
Case of upcasting usage
1 of the biggest advantages of upcasting is the capability of writing generic functions for all the classes that are derived from the aforementioned base class. Look at an example:
void congratulate(Employee* emp) { cout << "Happy Birthday!!!" << endl; emp->show(); emp->addBonus(200); };
This function will work with all the classes that are derived from the Employee form. When you telephone call it with objects of type Director and Person, they will be automatically upcasted to Employee class:
//automatic upcasting congratulate(&c1); congratulate(&m1);
Try to run this programme:
Happy Birthday!!!
Beginning Name: Kevin Last Proper noun: Jones
Happy Altogether!!!
Start Name: Steve Concluding: Name Kent
An example of how to use upcasting with virtual functions is described in the "C++ Polymorphism" topic.
Retentivity layout
As yous know, the derived class extends the properties of the base form. It means that derived class has properties (data members and member functions) of the base class and defines new data members and member functions.
Wait on the memory layout of the Employee and Managing director classes:
Of form, this model is a simplified view of memory layout for objects. Even so, information technology represents the fact that when y'all utilize a base class pointer to signal up an object of the derived class, you tin access only elements that are defined in the base form (green area). Elements of the derived class (yellow area) are not accessible when y'all utilise a base grade arrow.
DOWNCASTING
Downcasting is an reverse procedure for upcasting. Information technology converts base grade arrow to derived form pointer. Downcasting must exist done manually. It means that you have to specify explicit typecast.
Downcasting is not as safe as upcasting. You know that a derived class object can exist always treated as a base course object. However, the opposite is not correct. For example, a Director is ever a Person; Only a Person is not always a Manager. It could be a Clerk too.
Yous accept to utilise an explicit cast for downcasting:
//arrow to base of operations class object Employee* emp; //object of derived class Director m1("Steve", "Kent", 3000, 0.2); //implicit upcasting emp = &m1; //explicit downcasting from Employee to Managing director Managing director* m2 = (Manager*)(emp);
This code compiles and runs without any problem because emp points to an object of Manager class.
What will happen, if we endeavour to downcast a base form pointer that is pointing to an object of the base of operations class and not to an object of derived class? Try to compile and run this code:
Employee e1("Peter", "Light-green", 1400); //try to cast an employee to Manager Manager* m3 = (Managing director*)(&e1); cout << m3->getComm() << endl;
e1 object is non an object of the Manager form. It does not contain whatever data about the commission. That's why such an performance can produce unexpected results.
Look on the retention layout once again:
When you attempt to downcast base of operations form pointer (Employee) that is not really pointing upwardly an object of the derived class (Manager), you lot will go access to the retentiveness that does not have any information nigh the derived class object (xanthous expanse). This is the primary danger of downcasting.
Yous tin use a safe cast that tin can help you to know if i type tin can exist converted correctly to another type. For this purpose, utilize a dynamic cast.
Dynamic Cast
dynamic_cast is an operator that converts safely one type to another type. In the example, the conversation is possible and rubber, it returns the address of the object that is converted. Otherwise, it returns nullptr.
dynamic_cast has the post-obit syntax
dynamic_cast<new_type> (object)
If you want to apply a dynamic bandage for downcasting, the base class should be polymorphic – information technology must have at to the lowest degree one virtual function. Modify base of operations class Person by calculation a virtual function:
virtual void foo() {}
Now y'all tin can utilise downcasting for converting Employee class pointers to derived classes pointers.
Employee e1("Peter", "Green", 1400); Managing director* m3 = dynamic_cast<Managing director*>(&e1); if (m3) cout << m3->getComm() << endl; else cout << "Tin't cast from Employee to Managing director" << endl;
In this example, the dynamic cast returns nullptr. Therefore, you will see a warning message.
In this commodity, we have read well-nigh C++ Upcasting and Downcasting. In adjacent manufactures, nosotros will cover more topics on C++.
Reference
harnessyoughlythers.blogspot.com
Source: https://www.tutorialcup.com/cplusplus/upcasting-downcasting.htm
Post a Comment for "C Downcast to Interface Then Upcast Again"