【问题标题】:Cast to base class from base pointer from different base class (preferably without dynamic_cast)从不同基类的基指针转换为基类(最好没有dynamic_cast)
【发布时间】:2012-11-26 14:12:34
【问题描述】:
class Model {};

class AbstractModel {};
class TableModel : public AbstractModel {};

class CustomerModel : public TableModel, public Model {};
class ItemModel : public TableModel, public Model {};
...

要求是每个 TableModel 子类必须提供一组在所有子类(CustomerModel、ItemModel、...)之间共享的功能。由于 TableModel 和 AbstractModel 是不可变的,因此一组特性在 Model 类中定义并在每个子类(CustomerModel、ItemModel...)中实现。

现在的问题是应用程序的其他部分只能访问 AbstractModel 指针,并且为了访问 Model 中定义的一组特性,这个指针必须从 AbstractModel 转换为 Model(我们假设每个 TableModel 子类也实现了模型)。

是否有可能在不使用 dynamic_cast 的情况下这样做? 对提供相同功能的不同设计有何建议?

【问题讨论】:

  • 有什么理由不从Model继承AbstractModel

标签: c++ inheritance casting multiple-inheritance


【解决方案1】:

首先,如果没有dynamic_cast,这是不可能的。但是,您的要求对我来说听起来有点奇怪。 “每个 TableModel 子类都必须提供一组特性”听起来很像 TableModel 应该使用纯虚函数来定义该集合。你说 TableModel 是不可变的,所以我猜你是从某种库/框架中获得它并且正在实现你自己的一组子类,这是我们正在谈论的你的组需求。在这种情况下,我建议您派生一个 TableModel 抽象类,将您的需求定义为纯虚函数,并从该抽象类派生实际实现:

//immutable/library
class AbstractModel {};
class TableModel : public AbstractModel {};

//your code:
class MyOwnTableModel : public TableModel
{
public: 
  void implementThisRequrement() = 0;
};

class CustomerModel : public MyOwnTableModel { /*...*/ };
class ItemModel : public MyOwnTableModel { /*...*/ };

之后,您只需简单地从 AbstractModel 向下转换 (dynamic_cast) 到 MyOwnTableModel,无需交叉转换。但是,如果您能告诉我们更多关于您所拥有的设计的信息,也许有一个更简单、更好的解决方案 - dynamic_cast 几乎永远是某些设计缺陷的证据。

【讨论】:

  • 这是不可能的,因为继承树也可能是 AbstractModel -> SomeOtherModel -> CustomerModel。因此,implementThisRequirement() 是继承树中“太高”的一类。
  • 好的,但是,如果您能提供更多关于您的情况的信息(例如,为什么其他部分只能访问 AbstractModel 指针?AbstractModel 的接口是什么?)
【解决方案2】:

首先,为什么不使用 dynamic_cast?

第二,为什么不让TableModel继承Model呢? (毕竟,“表模型”听起来像是“模型”的特殊版本)

“不可变”是指在 Java/.NET 意义上,对象一旦创建就不能更改其状态?或者您的意思是您不能更改这些类,因为它们是某个库的一部分?我的第一个猜测是第一个。

如果您不想使用 dynamic_cast(这是 C++ 的 RTTI 功能的一部分),则必须实现自己的 RTTI 形式。例如,Microsoft 的 MFC 通过从包含运行时类型信息的 CObject 超类派生所有类来做到这一点。 Microsoft COM 还通过要求所有接口都从 IUnknown 接口派生来做到这一点,该接口包含一个基本等同于 dynamic_cast 的 QueryInterface 方法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-23
    • 1970-01-01
    相关资源
    最近更新 更多