Ich habe nie mit Mehrfachvererbung gearbeitet und bin über ein Designproblem gestolpert, mit dem ich nie konfrontiert war.
class A {
//..methods..
}
class B : public A {
int b;
//...methods..
}
class C : public A {
int c1,c2;
}
class D : public B,public C {
}
Hier ist der klassische Diamant. Die Tatsache ist, dass C
ist eigentlich nur ein A
mit zwei Extra-Int. und D
ist eigentlich nur eine Ansammlung von B
y C
aber ich habe das Gefühl, dass die Mehrfachvererbung nicht dazu gedacht ist, solche Dinge zu machen. Oder, dass es andere beste Praktiken, dies zu tun sein kann.
Der Grund, warum im versuchen, Mehrfachvererbung zu implementieren ist, dass ich eine Funktion wie schreiben möchten void func(A*)
und übergeben Sie ihm entweder eine A
o D
Klassenzeiger. Mein naiver Versuch besteht darin, einen einfachen Cast durchzuführen:
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..
}
}
Funktioniert nicht Kompiliert gut, aber ich habe ein wirklich seltsames Verhalten, wenn if(is_the_case)
ausgeführt wird, wodurch 2 zusätzliche Ints gelöscht werden c1
y c2
, klärt auch b
(vererbt von B
).
Ich erinnerte mich an das Problem mit den Diamanten, aber hier gibt es nur eines B
(und 2 A
) in der Hierarchie, daher verstehe ich nicht, warum b
wird ebenfalls geräumt. Nur um es zu versuchen, habe ich public virtual in B
y C
Erklärung. Jetzt ist jeder Cast ein Kompilierfehler, es sei denn, ich verwende eine dynamic_cast
..
Kann mir jemand erklären, was hinter den Kulissen passiert? Was ist die beste Vorgehensweise, wenn man bedenkt, dass es noch andere Klassen gibt wie:
class E : public A {
int e;
//..methods..
}
class F : public E,public C {
}
Das heißt, andere Klassen, die nur eine Aggregation einer Klasse sind, die von A
+ zwei zusätzliche Ints, geerbt von C
und das kann an eine Funktion übergeben werden, die *A
Danke, ich habe mein Bestes getan, um mich so klar wie möglich auszudrücken.