Ich habe x pure abstrakte Klassen (nur virtal ... = 0) die gemeinsam eine Schnittstellen Hierarchy aufbauen, teilweise gibt es Mehrfachableitung die aber in Ordnung ist weil das eben nur Interfaces sind, es gibt definitiv keine Members oder Code der der mehrfach abgeleitet wird (und wird es auch garantiert niemals geben) am Ende gibt es dann n echte Klasse welche diese Interfaces implementieren durch die Mehrfachableitung bei den Interfaces habe ich jetzt aber Probleme an die richtigen Pointer/Schnittstellen zu kommen weil ja trotz der pure-ness noch n mal das selbe Interface in der Hierachie drinn sein kann um das ganze homogen zu halten würde ich jetzt z.B. gerne beim Zusammenbau meiner Interface-Hierarchie immer mit virtual ableiten (auch als Regel für andere Entwickler) - nur die echte Implementierung ganz normal - damit wäre das technisch sauber und würde dann z.B. dem C# oder Java Interface Konzept entsprechen (ich könnte die virtual Ableitung natürlich auch nur dort machen wo ich sie brauchen aber so eine "mach es immer so Aussage wäre mir schon lieber") hier das C# Beispiel: https://dotnetfiddle.net/O06tsz das C++ "equivalent" https://onlinegdb.com/HJheVa9jN Gibt es Gründe die gegen einen pure abstrakt virtual Ableitungs-Hierarchie sprechen?
Sorry ganz vergessen: -Es geht mir nur um eine Lösung für C++ -die pure abstract Interfaces werden als Pointer über DLL-Grenzen verwendet (mit anderen C++ Kompilern z.B. Intel/Microsoft,...)
Virtuelle Ableitungen machen Objekte größer. Ist es wirklich notwendig, aus den Interfaces eine Hierarchie zu bauen?
>Virtuelle Ableitungen machen Objekte größer. aber immer nur um Pointer size, oder? sizeof() ohne virtual derive + ohne pure virtual = 1 byte ohne virtual derive + mit virtual = 8 byte mit virtual derive + mit pure virtual = 16 byte >Ist es wirklich notwendig, aus den Interfaces >eine Hierarchie zu bauen? Ja schon - und teilweise kommt es eben zu Mehfachableitung - bin mir aber noch nicht 1000% sicher
> Ja schon
Nein, wenn du schon bei deinen selbst verursachten Problemen hier
nachfragen musst, wird dir die Komplexität über den Kopf wachsen.
Im Betatest mit realen Aufgaben und realen Anwendern kommen noch einige
Anforderungen, die dein Konzept sprengen. War bisher bei allen Projekten
immer so.
Du musst die Interna so einfach und übersichtlich wie möglich anlegen.
Mit den unvorhersehbaren Anforderungen wird es später sowieso viel zu
komplex.
So was haben wir damals auch versucht schrieb: >> Ja schon > > Nein, wenn du schon bei deinen selbst verursachten Problemen hier > nachfragen musst, wird dir die Komplexität über den Kopf wachsen. Es ist ja kein Software-Design Problem - sondern erstmal nur eins von C++, in C#/Java ist das ja ohne irgendwelche Klimmzüge völlig problemfrei möglich, nur C++ kennt eben kein echtes Interface-Konzept sondern nur technisch einen Weg das so lala clean aus zu drücken > Im Betatest mit realen Aufgaben und realen Anwendern kommen noch einige > Anforderungen, die dein Konzept sprengen. War bisher bei allen Projekten > immer so. Bei böser Mehrfachableitung mit Daten und Code gebe ich dir 100% recht aber bei reinen Interfaces verstehe ich dich oder deine Bedenken nicht > Du musst die Interna so einfach und übersichtlich wie möglich anlegen. > Mit den unvorhersehbaren Anforderungen wird es später sowieso viel zu > komplex. Ich hab hier ein COM-artiges Konzept d.h. Objekt die x Interfaces implementieren und per DLL als Plugin zur Laufzeit rein kommen können - und Microsoft macht das nicht per virtual Ableitung sondern per static_cast<...> in den Factories, das sieht manchmal auch ganz schön übel aus, mit virtual Ableitung erreiche ich das gleiche ohne die fiesen static_casts aber bekomme eben fettere Objekte wenn ich dieses COM-artige Konzept/Plugins nicht hätte gäbe es diese Interface-Hierarchien gar nicht erst, weil die eben kompliziert sind
I.A. wird viel zu oft Vererbung verwendet, wo auch Komposition ausreichen würde. https://en.wikipedia.org/wiki/Composition_over_inheritance Des Weiteren solltest du dir überlegen, ob du wirklich Laufzeitpolymorphie mit dynamischen distpach (vtable) brauchst, oder ob statische Polymorphie nicht angebrachter wäre (Templates). Bei letzterer werden keine vtables benötigt und es hat keine Kosten zur Lauzeit.
Ich habe mich jetzt gerade noch mal durch diverse Dokus gelesen und fest gestellt das Microsoft bei COM auch die Mehrfachableitung von Schnittstellen verbietet - also geben ich euch allen erst mal recht das ich mir das noch mal genauer überlegen sollte, im Grunde will ich das ja auch nicht und es fühlt sich die ganze Zeit nicht ganz koscher an - also Danke für die Kommentare >Des Weiteren solltest du dir überlegen, ob du wirklich >Laufzeitpolymorphie mit dynamischen distpach (vtable) brauchst, oder ob >statische Polymorphie nicht angebrachter wäre (Templates). Bei letzterer >werden keine vtables benötigt und es hat keine Kosten zur Lauzeit. Ich habe aber eine abstrakte Schnittstelle die durch eine DLL-Schnittstelle durch muss, die von unterschiedliche Implementierungen haben - kann ich da auch mit statischer Polymorphie arbeiten?
CppBert3 schrieb: > https://onlinegdb.com/HJheVa9jN Deinen Code lese ich so: IB ist ein IA IC ist ein IB ID ist ein IA und ein IB und ein IC Jetzt versuche ich vergeblich ein Beispiel aus dem Alltag zu finden, welches man hiermit beschreiben könnte. Mein Gedanke war: IA = Auto IB = Peugeot IC = 206 ID = "Mein Auto" Dann würde Dein Code bedeuten: Peugeot ist ein Auto 206 ist ein Peugeot "Mein Auto" ist ein Auto und ein Peugeot und ein 206 Das macht jedoch keinen Sinn, da ein 206 ja bereits ein Peugeot ist und dieser wiederum ein Auto. Hierdurch ist "Mein Auto" ja zwei verschiedene Autos zur gleichen Zeit. Außerdem würde es "Mein Auto" zur Compile-Time bereits fest als 206 definieren, was eigentlich nicht gewollt sein kann. --- Wenn ich davon ausgehe, dass Du ein Basisobjekt hast (IA) und diesem Schritt für Schritt Eigenschaften hinzufügen willst, könnte ich hiervon ausgehen: IA = Hammer IB = Nageleisen IC = Holzgriff ID = Hammer mit Nageleisen und Holzgriff Dann hättest Du tatsächlich ein Objekt modelliert (ID), welches ein Hammer ist und ein Holzgriff und ein Nageleisen. Bestehend aus einem Holzgriff der ein Nageleisen ist und ein Hammer, sowie ein Nageleisen das ein Hammer ist. --- Damit ich jetzt aber sinnvolles Output geben kann, musst Du die Klassen (Ia,IB,IC und ID) benennen. --- > Es ist ja kein Software-Design Problem - sondern erstmal nur > eins von C++, in C#/Java ist das ja ohne irgendwelche > Klimmzüge völlig problemfrei möglich, nur C++ kennt eben kein > echtes Interface-Konzept sondern nur technisch einen Weg das > so lala clean aus zu drücken Nur weil etwas in XYZ möglich ist, heißt es nicht dass C/C++ schlecht ist. Und nein, es ist definitiv ein Software-Design-Problem. Meine Begründung hierfür: Wenn das Design gut ist, kannst Du es in jeder Programmiersprache ausdrücken. In Deinem Codebeispiel fehlt mir die "hat ein" Relation. Ich tippe also darauf, dass Du etwas mithilfe von Vererbung ("ist ein") modellieren möchtests, was man einfacher und logischer mit "hat ein" ausdrücken sollte. Ich diskutiere hier gerne weiter, aber nur wenn Du die Klassen (IA..ID) mit einem greifbaren Gegenständen benennst.
Horst schrieb: > Dann hättest Du tatsächlich ein Objekt modelliert (ID), welches ein > Hammer ist und ein Holzgriff und ein Nageleisen. Bestehend aus einem > Holzgriff der ein Nageleisen ist und ein Hammer, sowie ein Nageleisen > das ein Hammer ist. Bestehend aus -- Das deutet aber eigentlich eher auf Komposition hin, als auf Vererbung. Es müsste eher heißen, dass ein und dasselbe Objekt unterschiedlich aussehen kann/muss, um in verschiedenen Bereichen eingesetzt zu werden (interface).
https://de.wikipedia.org/wiki/KISS-Prinzip Sonst wird dir das alles in 2 Jahren um die Ohren fliegen, weil du selbst mit den komplexen Vererbungen nicht mehr klar kommst.
CppBert3 schrieb: > Ich habe aber eine abstrakte Schnittstelle die durch eine > DLL-Schnittstelle durch muss, die von unterschiedliche Implementierungen > haben - kann ich da auch mit statischer Polymorphie arbeiten? Das kann ich nicht beurteilen. Aber z.B. eine Frage, die du dir stellen kannst ist: "Ist zur Kompilierzeit das gewünschte Verhalten bekannt?" Wenn ja, dann könnte statische Polymorphie auch gehen. Beispiel: Ein std::vector<int> wird immer int beinhalten und nie struct foo. Bei einem Listentyp, der mal int, mal struct foo enthalten kann, und zur Laufzeit mal eine, mal eine andere Funktion/Methode aufgerufen werden soll, dann brauchst du dynamische Polymorphie. "Better Code: Runtime Polymorphism - Sean Parent": https://www.youtube.com/watch?v=QGcVXgEVMJg
1 | struct IA |
2 | {
|
3 | virtual void a() = 0; |
4 | };
|
5 | |
6 | struct IB : virtual IA |
7 | {
|
8 | virtual void b() = 0; |
9 | };
|
10 | |
11 | struct IC : virtual IB |
12 | {
|
13 | virtual void c() = 0; |
14 | };
|
15 | |
16 | struct ID : virtual IA, virtual IB, virtual IC |
17 | {
|
18 | virtual void d() = 0; |
19 | };
|
Was genau bezweckst du mit ID? IC bringt IA und IB schon mit, wofür deren nochmalige Vererbung an ID? Virtuelle Vererbung kann dann sinnvoll wein, wenn es parallel zu den Interfaces auch eine Hirarchie der Implementierungen dazu gibt. Oliver
:
Bearbeitet durch User
Oliver S. schrieb: > Was genau bezweckst du mit ID? IC bringt IA und IB schon mit, wofür > deren nochmalige Vererbung an ID? Das war jetzt schnell ein Beispiel für so eine Mehrfach-Ableitung von Interfaces - und mir ist auch klar geworden das ich solche Ableitungen definitiv vermeiden möchte, ich probiere im laufe der Woche noch ein paar Varianten durch und poste (wenn ich dazu komme) noch ein Update mit was sinnvollem Danke an alle
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.