将基类转换为指向子类的指针 - C ++

时间:2015-05-29 09:19:09

标签: c++ pointers inheritance casting dynamic-memory-allocation

这篇文章是这个Question的一个工作示例。但是,有些观点让我感到困惑。这就是我将其作为另一个问题发布的原因。

基本上,问题是如何将基类强制转换为其子类。人们建议使用动态内存并new新的子类实例。

我提出了以下解决方案,现在想知道这是如何工作的。我创建了一个基类(Employee)的对象。设置其ID。然后我将其指针转换为子类的指针并设置更多成员。

// 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;
}

为什么会这样?我看到如下:

员工:| --id-- | ... FullTimeEmployee:| --id-- | --grade-- | ...

1-这是在后台发生的事情吗?当我转向FullTimeemployee时,C ++会复制Employee类的所有预先存在的成员,并根据新的大小为您提供更多空间类型。

2-使用这种方法是否安全?我是否更喜欢动态内存分配,例如FullTimeEmployee *pFT1 = new FullTimeEmployee();这个?如果是,为什么?为什么我不能用指针式转换?

更新:此示例与投射到void*的不同之处是什么?你只是玩内存地址。只要你知道你需要多少记忆就会出错?

1 个答案:

答案 0 :(得分:2)

只有似乎才能正常工作,因为e1 不是任何子类的实例,导致undefined behavior

要使其正常工作,您需要使用动态内存分配:

Emplyoee *e1 = new FullTimeEmployee;

现在它适用于强制转换,因为e1实际指向FullTimeEmployee对象。

但你真的应该使用static_cast,比如

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

或者只是

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

另外,您应该阅读downcasting,这就是您正在做的事情。