当类的成员存储为没有此类方法的父类的对象时,如何访问该类的成员?

Posted

技术标签:

【中文标题】当类的成员存储为没有此类方法的父类的对象时,如何访问该类的成员?【英文标题】:How to access a member of a class when it is stored as a object of a parent class that has no such method? 【发布时间】:2019-02-07 12:21:01 【问题描述】:

我有一个层次结构,例如:

Element
|_Resitance
|_DC Voltage Source
|_AC Voltage Source
|_AC Current Source
|_DC Current Source
|_DynamicElement
|  |_Inductor
|  |_Capacitor
|_SwitchingDevices
|  |_Switch
|  |_Diode
.
.
.

由于我的输入可以是其中的任何列表,因此它们都插入到std::vector<Element*> 中。问题是二极管、开关和电压源有一个我必须访问的 ID 成员。

当我确定 Element 是具有此类成员的子类时,我希望能够运行 *(*Element).ID 或类似的东西。

我真的不想在 Element 类中包含 ID 成员,因为这种情况会经常发生,因为该类会有很多不合适的成员。

【问题讨论】:

所以你想downcast Element* 到例如Switch*? 我不熟悉这个术语,就我所读到的而言,是的。我可以用新类创建一个新指针,然后销毁该指针。 【参考方案1】:

将虚拟析构函数添加到基类并使用dynamic_cast<> 到派生类来访问其成员。 dynamic_cast dynamic_cast 如果对象不是您转换为的类型的实例,则引用将引发异常,而 dynamic_cast 通过指针将在相同情况下返回 nullptr

例子:

class Element

    ...
    virtual ~Element() = default;
;

...

Element * el = new Diode();
Diode * d = dynamic_cast<Diode *>(el);
if (d) 
// ok, this is diode

【讨论】:

这会删除el(为什么需要析构函数?)?我不需要干预向量的顺序,我必须访问成员而不更改el 的保存位置。 不,这不会删除el,它只是创建指向同一实例的Diode * 类型的指针。 那么,为什么需要虚拟析构函数呢? 您只能将dynamic_cast 用于具有虚拟方法表的类,因此此类必须至少包含一个虚拟方法,例如虚拟析构函数。 如果你的派生类有额外的数据成员,你应该使用虚拟析构函数来避免内存泄漏。

以上是关于当类的成员存储为没有此类方法的父类的对象时,如何访问该类的成员?的主要内容,如果未能解决你的问题,请参考以下文章

java如何调用父类的父类中被覆盖的方法

第五周学习总结

当类的成员方法接收的形式参数是抽象类或者是接口时,如何传参数?

课程作业09:继承与多态课件中动手动脑的相关问题。

java中,子类能调用父类中所有方法、对象吗?是不是父类也能调用子类所有……?

C++调用父类的构造函数规则