这篇文章是这个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*
的不同之处是什么?你只是玩内存地址。只要你知道你需要多少记忆就会出错?
答案 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,这就是您正在做的事情。