I'm currently trying to build a hierarchy of classes that uses multiple inheritance. I have classes A
, B
, C
and D
, related as such:
struct A
{
int a;
A(int a_) : a(a_) {}
};
struct B : virtual A
{
int b;
B(int a_, int b_) : A(a_), b(b_) {}
};
struct C : virtual A
{
C(int a_) : A(a_) {}
};
struct D : B , C
{
D(int a_, int b_) : A(a_), B(a_, b_) , C(a_) {}
};
My problem is that D
is passing arguments to B
and C
that aren't needed, and I'd like to find a better way of doing this.
The best way I found would be to have D
initialize B
first with B(a_, b_)
and then B
would initialize A
with A(a_)
and then I'd initialize C
with C(a_)
(even though the argument wouldn't matter) and 'link' C
's instance of A
to B
's A
instance.
What I mean by this is that the memory layout of D
would look something like this:
Where C
's base class A
would be located inside of B
.
I've tried multiple ways to do this in C++, but I haven't found one where it would let me change where C
's A
was located nor do I know if it possible.
My question is if this is possible to achieve in C++ using inheritance or possibly another tool?
Even if it possible, I would still have the problem of having to initialize both B
and C
with a 'dummy' argument that wouldn't do anything, this is fine for an int, but not for something more 'heavy'.
What I would want is for, when inheriting from B
or C
, you'd use an empty constructor to initialize it, and would use the other constructor when creating it normally, something like this:
struct A
{
int a;
A(int a_) : a(a_) {}
};
struct B : virtual A
{
int b;
B(int a_, int b_) : A(a_), b(b_) {}
protected:
// The A initialization will never get called
B(int b_) : A(0), b(b_) {}
};
struct C : virtual A
{
C(int a_) : A(a_) {}
protected:
// This initialization will never get called
C() : A(0) {}
};
struct D : B , C
{
D(int a_, int b_) : A(a_), B(b_) , C() {}
};
The only problem is that I'm not sure this has any side effects I should be aware of, or if it even works, I couldn't think of a way to test it well.
I'm not sure if asking two questions in one is acceptable, I believe that they make sense together, but if not, I'll edit it out and ask it as a different question.
Edit 1:
In relation to the duplicate, that answer states that the unused arguments will not be used to initialize the base-most class in the two derived classes.
My second question is how can I avoid having to provide the unused parameters to the two derived classes as the arguments can be very big and take a long time and memory copying. I have provided a possible solution, but I am not sure if this actually solves my problem and what side effects it can have.
Thus more concretely, my second question is Is this implementation of avoiding providing the parameters to the two derived classes good or are there any side effects I haven't taken in to account while building it?