Я никогда не использовал множественное наследование и столкнулся с проблемой дизайна, с которой никогда не сталкивался ..
class A {
//..methods..
}
class B : public A {
int b;
//...methods..
}
class C : public A {
int c1,c2;
}
class D : public B,public C {
}
Вот классический ромб. Дело в том, что C
на самом деле просто A
с двумя дополнительными int. и D
на самом деле просто совокупность B
и C
, но мне кажется, что множественное наследование не предназначено для создания подобных вещей. Или что для этого могут быть другие передовые методы.
Причина, по которой я пытаюсь реализовать множественное наследование, заключается в том, что я хочу написать такую функцию, как void func (A *)
, и передать ее либо Указатель класса
или D
. Моя наивная попытка - сделать простое приведение:
void func(A* a) { // <-- I call this with a A or D pointer
// ..do something with A members..
if(is_the_case) { // <-- Im sure the passed "a" pointer is actually a *D
D* d = (D*)a;
// ..do something with the extra 2 ints provided by the C class..
}
}
Не работает .. Компилируется нормально, но у меня действительно странное поведение, когда выполняется if (is_the_case)
, очищая эти 2 лишних int ] c1
и c2
, очищает также b
(наследуется от B
).
Я вспомнил о проблеме с алмазом, но здесь есть только один B
(и 2 A
) в иерархии, поэтому я не понимаю, почему b
также очищается. Чтобы попробовать, я использовал публичный виртуальный объект в декларации B
и C
. Теперь каждое приведение является ошибкой компиляции, если я не использую dynamic_cast
..
Может кто-нибудь прояснить, что происходит за кулисами? Как лучше всего это сделать, учитывая, что существуют другие классы, такие как:
class E : public A {
int e;
//..methods..
}
class F : public E,public C {
}
То есть другие классы, которые являются просто агрегацией класса, производного от A
+ два дополнительных целых числа, унаследованных от C
и это может быть передано функции, которая принимает * A
Спасибо, я постарался быть максимально понятным ..