几天前我问了一些 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
元素。经过一些进一步的分析,我能够将后者正确分类为 Hand
或 Head
并相应地修改 vector 中的元素,但我不知道如何制作它。我应该删除 case class 元素并创建一个具有相同属性的派生元素吗?在这种情况下,我应该避免继承吗?先谢谢您的帮助
最佳答案
编辑:我增加了示例以使它们更清晰。
使用类型转换通常是糟糕设计的标志。 Actor 有他们的位置,但这看起来不是它。
您需要问问自己,您想对 cBodyParts
中存储的对象做什么。当然,您将使用 Hand
或 Head
做不同的事情,但您可能可以以某种方式抽象它们:这就是虚函数所做的。因此,除了您已经为类编写的内容之外,您只需要在其中添加一个额外的虚函数:
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
循环将与它找到的 Torso
或 Leg
一起正常工作,无需更新。关于c++ - 将基类的对象转换为派生类,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/14232656/