简体   繁体   English

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

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

This post is a working example for this Question . 这篇文章是此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. 人们建议使用动态内存并为子类new一个实例。

I cam up with the following solution, and now wonder how this works. 我提出了以下解决方案,现在想知道它是如何工作的。 I create an object of the base class (Employee). 我创建基类(Employee)的对象。 Set its Id. 设置其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--|... 员工:| --id-- | ... FullTimeEmployee:| --id-- |-等级-| ...

1- Is this what happens in the background? 1-这是在后台发生的吗? 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. 当我强制转换为FullTimeemployee时,C ++复制Employee类的所有现有成员,并根据新类型的大小为您提供更多空间。

2- Is it safe to use this approach? 2-使用这种方法安全吗? Should I prefer dynamic memory allocation, eg FullTimeEmployee *pFT1 = new FullTimeEmployee(); 我应该动态分配内存FullTimeEmployee *pFT1 = new FullTimeEmployee(); ,例如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* ? 更新:是什么使该示例与强制转换为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 . 似乎只起作用,因为e1 不是任何子类的实例,从而导致未定义的行为

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. 现在,它可以进行强制转换,因为e1实际上指向FullTimeEmployee对象。

But you should really use static_cast , like 但是您应该真正使用static_cast ,例如

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. 另外,您还应该阅读有关垂降的内容 ,这就是您正在做的事情。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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