I have a diamond inheritance scheme in C++ solved through virtual inheritance.
The base class is general
has two attributes and some method using them.
class general {
double attr1, attr2;
public:
general(double attr1, double attr2) {
this->attr1=attr1;
this->attr2=attr2;
}
virtual double somemethod() {
return attr1*attr2;
}
};
A specialrestriction
is a general
with a special restriction that both attributes are equal.
class specialrestriction : public general {
public:
specialrestriction(double attr) : general(attr, attr) {};
};
A specialrule
slightly modifieds somemethod()
with a special rule.
class specialrule : public general {
public:
specialrule(double a, double b) : general(2*a, 2*b) {}
double somemethod() override {
return general::somemethod()*0.785398;
}
};
Finally a restrictionandrule
is a general
with the same restriction as a specialrestriction
(I would like to use its constructor), and the same special rule for computing the somemethod()
as a specialrule
(I would like to use its somemethod()
method). The solution I have so far is:
class restrictionandrule : public virtual specialrule, public virtual specialrestriction {
public:
restrictionandrule(double attr) : specialrestriction(attr), specialrule(attr,attr) {} //the call to the constructor of specialrule is (almost?) redundant
double somemethod() override { return specialrule::somemethod(); } //only specialrule overrides somemethod(), is there another way to
};
int main() {
restrictionandrule c(5);
std::cout<<"restrictionandrule::somemethod is " << c.somemethod()<<std::endl;
return 0;
}
As put in the code's comments, I think the code of restrictionandrule
is redundant. My intention when doing this was avoiding as much code redundancy as possible, but couldn't go any further.
(As a side comment, I'd like the language to solve the somemethod()
ambiguity with less code (e.g., by calling the first parent's method by default), but to my knowledge that's just the standard, and this is not my question.)
My question is this: Since both specialrule
and specialrestriction
do little more (from the programmer's POV, I know I'm oversimplifying!) than calling the base constructor, I don't really need both of them, but C++ enforces calling both. Is there a better way to do this? Do I have this problem because I'm misunderstanding the `an A is a B' relationship? (perhaps because derived classes are not supposed to have less attributes than the base?)