微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

当两个继承的类都需要一个不同的成员时,如何处理多重继承?

如何解决当两个继承的类都需要一个不同的成员时,如何处理多重继承?

我有以下课程:

class ServoPart {
protected:
    virtual void doJob(byte* job) = 0;

private:
    bool moving;
    Servo servo;
};

// the following classes only have a constructor so I can use two ServoParts to inherit from
class Major: public ServoPart {};
class Minor: public ServoPart {};

class Arm: public Major,public Minor {
private:
    void move() {
        // do stuff
        if (target == current) {
            moving = false;
        }
    };

public:
    void doJob(byte* job) {/* do stuff */};
};

我不能使用虚拟继承(我认为),因为 Major 和 Minor 需要分别控制一个不能相同的伺服器。但是,当 Arm 完成移动时,它应该将 moving 成员设置为 false。当我输入 ServoPart::moving 时,Intellisense 显示 moving

moving 的这种访问会产生歧义吗?如果是,我该如何解决这个问题?我对虚拟继承的假设是否因为我有两个不同的伺服系统而无法使用它,对吗?

解决方法

是的,它是模棱两可的,编译器会抱怨。 您可以在 Major::moving 的成员函数的代码中编写 Minor::movingArm 来指定您想要的。

我怀疑你在这里是否有适当的“isa”关系。手臂不是马达。一个手臂两个电机。您应该在这里使用组合而不是继承。请注意,MajorMinor 没有任何虚函数,因此没有理由更喜欢继承。

试试:

class Arm {
   Major major;
   Minor minor;
   void move() {
     ...
     major.moving= false;
     minor.moving= false;
     ...

现在如何引用组件更加明显。但是对于(多重)继承,它是相同的想法。我认为您也在引入名称 MajorMinor 只是为了绕过继承多个副本的限制。如果您使用组合,则可以避免这种情况:

class Arm {
   ServoPart major;
   ServoPart minor;
...

或者,因为它们现在是相同的类型,也许可以创建一个数组。这使得向所有人“广播”相同的操作变得容易:

class Arm {
    ServoPart joints[2];
    void move() {
        ...
        for (auto j : joints)  j.moving= false;

更新

您的评论表明 ServoPart 具有虚拟 doJob 功能。你应该把它分成一个没有数据成员的纯接口,并从中派生出你的单电机类。您的复合类也可以从该接口继承。

struct Servo_Interface {
    virtual void doJob() =0;
};

class Joint : Servo_Interface {
    bool moving;
    Servo servo;
public:
    void doJob()  override;
};

class Arm : Servo_Interface {
    Joint joints[2];
public:
    void doJob()  override;
};

请注意,doJobArm 的实现可以为其包含的每个组件调用 doJob,但它是一个单独的函数,不会自动依赖它们。单个 JointArm 实例都可以被多态处理,因为它们有一个公共接口。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。