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

mat*_*tor 1 c++ multiple-inheritance virtual-inheritance ambiguous

我有以下课程:

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 */};
};
Run Code Online (Sandbox Code Playgroud)

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

这种访问moving会模棱两可吗?如果是,我该如何解决这个问题?我对虚拟继承的假设是我不能使用它,因为我有两个不同的伺服器,对吗?

JDł*_*osz 6

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

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

尝试:

class Arm {
   Major major;
   Minor minor;
   void move() {
     ...
     major.moving= false;
     minor.moving= false;
     ...
Run Code Online (Sandbox Code Playgroud)

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

class Arm {
   ServoPart major;
   ServoPart minor;
...
Run Code Online (Sandbox Code Playgroud)

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

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

更新

您的评论表明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;
};
Run Code Online (Sandbox Code Playgroud)

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