几天前我问了一些 clarifications on inheritance ,一个我仍在努力理解的概念。这是后续问题,因为我仍然面临问题。

在我的项目中,我有两种类型的对象,Hand 和 Face,它们都继承自基类 BodyPart。 BodyPart 是这样的:

class BodyPart
{
  public:
  typedef boost::shared_ptr<BodyPart> BodyPartPtr;

  BodyPart();
  virtual ~BodyPart();

  private:
  int commonMember1;
  double commonMember2;

  public:
  int commonMethod1();
  int CommonMethod2();
}

而 Hand 是这样的:
class Hand : public BodyPart
{
  public:
  Hand();
  ~Hand();

  private:
  int numFingers;
  double otherVar;

  public:
  int getNumFingers();
  void printInfo();
}

我还有一个 BodyPart 元素的 vector
std::vector<BodyPart::BodyPartPtr> cBodyParts;

由 Hand 或 Head 对象组成。在上一个问题中,我被告知这种方法是有道理的,我只需要使用 boost static_pointer_cast 从基类转换到派生类

现在,现在的问题是,对于 vector 中的某些对象,我不知道它们是 Hand 还是 Head ,所以在我的代码中的某个时刻,我可以在 cBodyParts 中包含一些 Hand 元素、一些 Head 元素以及一些BodyPart 元素。经过一些进一步的分析,我能够将后者正确分类为 HandHead 并相应地修改 vector 中的元素,但我不知道如何制作它。我应该删除 case class 元素并创建一个具有相同属性的派生元素吗?在这种情况下,我应该避免继承吗?

先谢谢您的帮助

最佳答案

编辑:我增加了示例以使它们更清晰。

使用类型转换通常是糟糕设计的标志。 Actor 有他们的位置,但这看起来不是它。

您需要问问自己,您想对 cBodyParts 中存储的对象做什么。当然,您将使用 HandHead 做不同的事情,但您可能可以以某种方式抽象它们:这就是虚函数所做的。因此,除了您已经为类编写的内容之外,您只需要在其中添加一个额外的虚函数:

class BodyPart
{
  // Same as you wrote, plus:
public:
  virtual void InitialisePart() = 0; // Pure virtual: each body part must say how to process itself
  virtual void CalibrateJoints() {} // Override it only if the body part includes joints
}

class Head : public BodyPart
{
  // Same as you wrote, plus:
public:
  virtual void InitialisePart() {
    // Code to initialise a Head
  }
  // Since a Head has no joints, we don't override the CalibrateJoints() method
}

class Hand : public BodyPart
{
  // Same as you wrote, plus:
public:
  virtual void InitialisePart() {
    // Code to initialise a Hand
  }
  virtual void CalibrateJoints() {
    // Code to calibrate the knuckles in the hand
  }
}

然后你不再需要任何 Actor 。例如:
for (BodyPart::BodyPartPtr part : cBodyParts) {
  part->InitialisePart();
  part->CalibrateJoints(); // This will do nothing for Heads
}

如您所见,根本没有类型转换,一切都会正常工作。这个方案是可扩展的;如果您后来决定需要从 BodyPart 继承的其他类,只需编写它们,您的旧代码就会正常工作:
class Torso : public BodyPart
{
public:
  virtual void InitialisePart() {
    // Code to initialise a Torso
  }
  // The Torso has no joints, so no override here for CalibrateJoints()

  // Add everything else the class needs
}

class Leg : public BodyPart
{
public:
  virtual void InitialisePart() {
    // Code to initialise a Leg
  }
  virtual void CalibrateJoints() {
    // Code to calibrate the knee
  }

  // Add everything else the class needs
}

现在您不需要更改您之前编写的代码:上面的 for 循环将与它找到的 TorsoLeg 一起正常工作,无需更新。

关于c++ - 将基类的对象转换为派生类,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/14232656/

10-12 15:59