[英]How to handle multiple inheritance when both inherited classes need a distinct member?
I have the following classes:我有以下课程:
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 */};
};
I can't use virtual inheritance (I think) because the Major and Minor need to control one servo each which can't be the same.我不能使用虚拟 inheritance(我认为),因为 Major 和 Minor 需要分别控制一个不能相同的伺服。 However, when the Arm is done moving, it should set the
moving
member to false.但是,当 Arm 完成移动时,应将
moving
构件设置为 false。 Intellisense shows ServoPart::moving
, when im typing moving
.当我输入移动时,智能感知显示
ServoPart::moving
moving
。
Would this access of moving
be ambiguous?这种
moving
的访问方式会模棱两可吗? If yes, how can I fix this?如果是,我该如何解决这个问题? Is my assumption about virtual inheritance, that I can't use it because I have two different servos, correct?
我对虚拟 inheritance 的假设是因为我有两个不同的伺服系统,所以我不能使用它,对吗?
Yes, it is ambiguous and the compiler will complain.是的,它是模棱两可的,编译器会抱怨。 You can write
Major::moving
or Minor::moving
within the code of Arm
's member functions to specify which you want.您可以在
Arm
的成员函数的代码中编写Major::moving
或Minor::moving
来指定您想要的。
I question whether you have a proper "isa" relationship here.我怀疑你在这里是否有适当的“isa”关系。 An arm is not a motor.
arm 不是电机。 An arm has two motors.
arm有两个电机。 You should be using composition here instead of inheritance.
您应该在这里使用合成而不是 inheritance。 Note that
Major
and Minor
don't have any virtual functions so there is no reason to prefer inheritance.请注意,
Major
和Minor
没有任何虚拟功能,因此没有理由更喜欢 inheritance。
Try:尝试:
class Arm {
Major major;
Minor minor;
void move() {
...
major.moving= false;
minor.moving= false;
...
It is more obvious now how to refer to the components.现在如何引用组件更加明显。 But with (multiple) inheritance it is the same idea.
但是对于(多个)inheritance 是相同的想法。 I think also you are introducing the names
Major
and Minor
just to get around the limit of inheriting more than one copy.我认为您还引入名称
Major
和Minor
只是为了绕过继承多个副本的限制。 If you used composition, you can avoid that:如果您使用合成,则可以避免:
class Arm {
ServoPart major;
ServoPart minor;
...
Or, since they are the same type now, perhaps make an array instead.或者,由于它们现在是相同的类型,也许可以创建一个数组。 This makes it easy to "broadcast" the same operation to all of them:
这使得向所有人“广播”相同的操作变得容易:
class Arm {
ServoPart joints[2];
void move() {
...
for (auto j : joints) j.moving= false;
Your comment indicates ServoPart
has a virtual doJob
function.您的评论表明
ServoPart
有一个虚拟doJob
function。 You should separate that into a pure interface that has no data members, and derive your single-motor class from that.您应该将其分离为没有数据成员的纯接口,并从中派生出您的单电机 class。 Your composited class can also inherit from that interface.
您的复合 class 也可以从该接口继承。
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;
};
Note that the implementation of doJob
in Arm
can call doJob
for each of the components it contains, but it is a separate function that does not have any automatic reliance on them.请注意,
doJob
中的Arm
的实现可以为其包含的每个组件调用doJob
,但它是一个单独的 function,不会自动依赖它们。 Both single Joint
and Arm
instances can be treated polymorphically since they have a common interface.单个
Joint
和Arm
实例都可以进行多态处理,因为它们具有通用接口。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.