简体   繁体   中英

Casting a pointer toc the base class to a pointer to subclass - C++

This post is a working example for this Question . However, there are some points that confuse me. That is why I am posting it as another question.

Basically, the problem is how to cast a base class to its subclasses. People have suggested using dynamic memory and new ing a fresh instance of the subclass.

I cam up with the following solution, and now wonder how this works. I create an object of the base class (Employee). Set its Id. Then I cast its pointer to a pointer of the subclass and set more members.

// Example program
#include <iostream>
#include <string>
#include <list>
#include <algorithm>
using namespace std;

class Employee {
 public:
  int getId() { return id;}
   void setId( int id) {this->id = id;}
 protected:
  int id;

};

class PartTimeEmployee : public Employee {

};

class FullTimeEmployee : public Employee {
 public:
  int getGrade() {return grade;}
  void setGrade(int grade) {this->grade = grade;}
 private:
  int grade;
};

class Organization {
 public:    
  void addEmployee(Employee* e) { empList.push_back(e); }
  Employee* getEmployee(int id) { 
      for (std::list<Employee*>::iterator it=empList.begin(); it!=empList.end(); ++it) {
          if((*it)->getId() == id) {return (*it);}
      }
      return NULL; 
  }
 private:
  std::list<Employee*> empList;
};

int main()
{
  Employee e1;
  e1.setId(5);

  FullTimeEmployee *pFt1 = (FullTimeEmployee*) &e1; 
  pFt1->setGrade(1);                

  Organization org1;
  org1.addEmployee(pFt1);
  FullTimeEmployee* pFt2 = (FullTimeEmployee*) org1.getEmployee(5);
  cout << pFt2->getId() << endl;
  cout << pFt2->getGrade() << endl;
}

Why does it work? I see it as follows:

Employee: |--id--|... FullTimeEmployee: |--id--|--grade--|...

1- Is this what happens in the background? When I cast to the FullTimeemployee, C++ copies all pre-existing members of the Employee class plus giving you more space based on the size of the new type.

2- Is it safe to use this approach? Should I prefer dynamic memory allocation, eg FullTimeEmployee *pFT1 = new FullTimeEmployee(); over this? If yes why? why can't I just go with pointer casting?

UPDATE: What makes this example different from casting to void* ? You just play with memory addresses. What can go wrong as long as you know how much memory you need?

It only seems to work, because e1 is not an instance of any of the child classes, leading to undefined behavior .

To make it work, you need to use dynamic memory allocations:

Emplyoee *e1 = new FullTimeEmployee;

Now it works with the casting, because e1 actually points to a FullTimeEmployee object.

But you should really use static_cast , like

FullTimeEmployee *pFt1 = static_cast<FullTimeEmployee*>(e1);
pFt1->setGrade(1);

Or just

static_cast<FullTimeEmployee*>(e1)->setGrade(1);

Also you should read about downcasting , which is what you are doing.

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