【问题标题】:C++ How to use stand-alone base object from derived objectC ++如何使用派生对象中的独立基础对象
【发布时间】:2014-11-04 11:23:41
【问题描述】:

我有 3 节课。一个是基地,一个是父母,一个是孩子。父级在某个时刻被实例化并分配数据。在某些情况下,它被直接使用,但在其他情况下,需要在其子类中实现功能。

我想做的是将父对象转换为子对象,以便将其虚函数与父对象的数据一起使用:

class UndoBase : public QUndoCommand
{
public:
    UndoBase() {}    

    virtual void undo() = 0;
    virtual void redo() = 0;
};

class CommandParent : public UndoBase
{
public:
    CommandParent() {}

    virtual void undo()
    virtual void redo()

protected:
    someType data
};

class CommandChild : public CommandParent
{
public:
    CommandChild() {}

    virtual void undo() //overrides parent
    virtual void redo() //overrides parent
};

我试过这个:

CommandParent *parent = new CommandParent;
//assign data
UndoBase *command = static_cast<CommandChild*>(parent);
command->redo();

它有效(使用了 CommandChild 实现和 CommandParent 数据),尽管我发誓它应该是未定义的行为(我知道这也可以有效)。由于我怀疑这是正确的做法,所以我想问一下这是否可以,或者除了合成之外是否还有其他方法。

【问题讨论】:

  • 如果您将对象创建为父对象,则它永远不会成为/转换为子对象。您必须将其实例化为孩子,将其视为父母,有时将其视为孩子。
  • ommandParent *parent = new CommandParent;,在此行之后对CommandChild 的任何考虑根本都是错误的。不存在这样的物体,而且你不会通过挥动魔杖来神奇地创造一个。
  • 是的,我明白了。有什么方法可以将基础对象“注入”到子对象中作为其基础?
  • @Resurrection 没有标准的 AFAIK。你最好改变你的设计中的一些东西
  • 什么? “基础对象”UndoBase 已经在CommandChild 的继承层次结构中。您要解决的真正问题是什么?直接从CommandChild 对象指针/引用调用某个成员,例如:CommandParent::redo(),而不是咬入虚拟覆盖苹果?

标签: c++ inheritance derived-class


【解决方案1】:
UndoBase *command = static_cast<CommandChild*>(parent);

这条线的每一寸都是地狱。您告诉 static_cast 转换为 CommandChild 而您将其存储在 UndoBase 中。

您还尝试将 CommandParent 转换为 CommandChild 意味着 Base 到 Derived,其中 Base 类不知道派生转换。即使你写得好。

CommandChild  *child = static_cast<CommandChild*>(parent);

这将是错误的。除此之外,在这些情况下始终使用 dynamic_cast。它显式检查是否可以进行强制转换。如果强制转换安全,dynamic_cast 将正确强制转换,如果无法强制转换为目标类型,则返回 NULL(在指针的情况下,对于引用,它会抛出 bad_cast 异常)。

【讨论】:

    【解决方案2】:

    您必须使用复制构造函数使用来自 CommandParent 的数据创建一个新的 CommandChild 实例。

    UndoBase *command = new CommandChild(*parent);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-02-26
      • 2018-08-18
      • 1970-01-01
      • 2019-03-23
      • 2020-10-11
      相关资源
      最近更新 更多