В настоящее время я пытаюсь построить иерархию классов, которая использует множественное наследование. У меня есть классы A
, B
, C
и D
, связанные так:
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_) {}
};
Моя проблема в том, что D
передает аргументы B
и C
, которые не нужны, и я хотел бы найти лучший способ сделать это.
Лучший способ, который я нашел, - это D
инициализировать B
сначала с B(a_, b_)
, а затем B
инициализировать A
с A(a_)
, а затем я бы инициализировал C
с C(a_)
(хотя аргумент не имеет значения) и 'link' C
экземпляр A
к B
A
экземпляр.
Под этим я подразумеваю, что схема памяти D
будет выглядеть примерно так:
Где базовый класс C
A
будет находиться внутри B
.
Я пробовал несколько способов сделать это в C ++, но я не нашел такого, где он позволил бы мне изменить местоположение C
A
, и при этом я не знаю, возможно ли это.
Мой вопрос: возможно ли достичь этого в C ++, используя наследование или, возможно, другой инструмент?
Даже если бы это было возможно, у меня все равно была бы проблема инициализации как B
, так и C
с помощью аргумента 'dummy', который ничего не делал, это хорошо для int, но не для чего-то более «тяжелый».
Я бы хотел, чтобы при наследовании от B
или C
вы использовали пустой конструктор для его инициализации и использовали другой конструктор при его обычном создании, что-то вроде этого:
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() {}
};
Единственная проблема в том, что я не уверен, что у этого есть какие-либо побочные эффекты, о которых я должен знать, или, если это даже работает, я не мог придумать, как это проверить хорошо.
Я не уверен, приемлемо ли задавать два вопроса в одном, я считаю, что они имеют смысл вместе, но если нет, я отредактирую его и задам как другой вопрос.
Редактировать 1:
В отношении дубликата этот ответ гласит, что неиспользуемые аргументы не будут использоваться для инициализации самого базового класса в двух производных классах.
Мой второй вопрос: как мне избежать предоставления неиспользуемых параметров двум производным классам, поскольку аргументы могут быть очень большими и занимать много времени и копировать память. Я предоставил возможное решение, но я не уверен, что это действительно решит мою проблему и какие побочные эффекты это может иметь.
Таким образом, более конкретно, мой второй вопрос Является ли эта реализация предотвращения предоставления параметров двум производным классам хорошей или есть какие-либо побочные эффекты, которые я не учел при создании?