Hallo,
ich habe ein Diamantenproblem. Leider konnte ich im Netz keine Lösung
finden. (aber zumindest hab ich herausgefunden, wie sich das Problem
nennt. ;) )
Ich möchte folgende Klassen:
Vereinfacht aus "diamond_a.cpp"
1
class istream {
2
protected:
3
application *app;
4
}
5
class ostream {
6
protected:
7
application *app;
8
}
9
class test : public istream, public ostream {
10
// auch in dieser Klasse wird app benötigt
11
}
hierbei gilt: innerhalb der Vererbung zeigt istream::app, ostream::app,
test::app immer auf das selbe Objekt (muss!)! Nur der Compiler wird das
vermutlich nicht verstehen. Darum dachte ich, ich mache eine Basisklasse
für istream und ostream:
Vereinfacht aus "diamond_b.cpp"
1
class iostream {
2
protected:
3
application *app;
4
};
5
class istream : virtual public iostream {
6
// in dieser Klasse wird app benötigt
7
8
};
9
class ostream : virtual public iostream {
10
// in dieser Klasse wird app benötigt
11
12
};
13
class test : public istream, public ostream {
14
// in dieser Klasse wird app benötigt
15
};
nur wie baue ich jetzt die constructors für die jeweiligen Klassen, dass
alles korrekt initialisiert wird?
Ich hoffe, ich konnte mein Problem verständlich schildern.
Vielen Dank
Moin,
so ganz habe ich nicht verstanden, warum du App unbedingt in den
Streamklassen brauchst, Das gehört eigentlich nicht dahin. Vielleicht
ist auch der Name Application irreführend. Klingt, als wäre das die
übergeordnete Anwendung.
Nur für die Puffergröße ist das aber auch albern. Dann sollte die App
die Streams als Member haben und von dort stellst du dann den Puffer
ein.
Danke für eure Antworten.
@Dr. Sommer: ich denke mal darüber nach.
nicht"Gast" schrieb:> Vielleicht> ist auch der Name Application irreführend.
Gut möglich, ich tu mich mit dem benennen von Klassen und Funktionen
immer schwer. :(
in der applikation-klasse wird u.A. auch die sample rate gespeichert,
und geplant sind auch events (z.B. onSampleRateChange) wo sich die
Objekte registrieren können, um dann entsprechend reagieren zu können
(Koeffizienten neu berechnen, Puffer vergrössern). Also im Prinzip soll
alles da rein, was potentiell die ganze Anwendung betrifft, aber nicht
statisch ist. Vielleicht wäre setting ein passenderer Name.
Insbesonders ist es notwendig, die indirekte Basisklasse iostream vom
test-Konstruktor aus aufzurufen, weil es eine virtuelle Basisklasse ist
und test die oberste Klasse in der Hierarchie (sog. "most-derived
class").
Habe gerade gemerkt, dass das Problem - wie so oft - gar nicht dort
steckt, wo ich dachte. Es hat allerdings immer noch mit dem
diamond-problem zu tun, und zwar dann wenn man diesen weiter vererbt.
das funktioniert:
Wie gesagt, wenn man eine virtuelle Basisklasse hat, dann kann man deren
Initialisierung nicht delegieren, jede "most-derived class" muss es
immer wieder selbst machen:
Danke dir, tictactoe! Funktioniert!
Aber um ehrlich zu sein, verstehe ich die Logik dahinter nicht.
Dass "interface" "iostream" explizit initialisieren muss, kann ich noch
verstehen. Aber wenn "test" "interface" und "iostream" initialisiert,
wird "iostream" doch dann zwei mal initialisiert (einmal direkt und
einmal über "interface")... hmmm...
Nein, weil bei virtueller Vererbung immer die am weitesten abgeleitete
Klasse die virtuelle Basis inizialisiert. Wenn du also ein test
erzeugst, initialisiert das darin enthaltene interface dann nicht den
iostream.