Exception werfen beim Aufruf einer virtuellen Methode



  • Simon2 schrieb:

    Jester schrieb:

    ...Manchmal können eben doch alle As irgendwas. Nur eine Ausnahme gibt es: Cs sind zwar As, aber eine einzige Funktion unterstützen sie doch nicht....

    Dann sind sie eben keine As.
    So einfach ist das.

    Jo, so einfach ist das. Einfach und falsch. Lies doch zum Beispiel mal Multi-Paradigm Design for C++. Stichwort: negative variability. Vielleicht liefert auch google was dazu.

    edit:

    Beispiel aus dem Buch: eine Message-Klasse. Davon erben unterschiedliches Messages. Messages haben üblicherweise einen body. Nur manche messages sind Ausnahmen, die haben keinen body (es sind ganz wenige und messages sind es trotzdem). Soll jetzt die Basisklasse etwa keine Funktion zum Zugriff aus den body bieten? Willste lieber bei jeder normalen Message nen downcast reinbaun? Also den üblichen Fall verkomplizieren?



  • Jester schrieb:

    ...Jo, so einfach ist das. Einfach und falsch...

    "Für jedes noch so komplizierte Problem gibt es eine Lösung, die einfach, allgemeinverständlich, logisch und falsch ist."
    (Prof. H. Lesch)
    😉

    Wie schon gesagt: Es mag in der Praxis und im Spezialfall die am wenigsten schlechte Lösung sein, aber als "Normalfall" kann ich es trotzdem nicht sehen.
    Ich sage mal so: Wenn so etwas in einem Anfängerprogramm auftaucht, gibt es in mindestens 80% der Fälle eine bessere Lösung.
    Zu Deinem Fall (Ja, ich kenne das Buch NICHT): D.h. bei den "bodylosen Messages" mußt Du jede "body-bezogene Funktion" auf Dauer pflegen und in allen Zusammenhängen, in denen Du Messages nutzt, daran denken, dass es welche gibt/geben könnte, die keinen haben und entsprechende "Sonderlocken" berücksichtigen.

    Darin kann ich keinen Vorteil sehen.
    Mal abgesehen davon, dass wir hier schlechte Erfahrungen damit gemacht haben, "Messages" zu allzu selbständigen Objekten zu machen, sehe ich nicht, wieso man nicht die Hierarchie entsprechend erweitern sollte auf "BodyLessMessage" und "BodyFullMessage" oder schon die Messageklasse mit der "Optionalität" zu versehen (sprich: eine "virtual bool hasBody() = 0").
    In beiden Fällen wäre alles klar.

    Gruß,

    Simon2.



  • Beide Fälle verdecken die eigentliche Gemeinsamkeit und spielen sie in den Hintergrund, obwohl sie sich nur in einer Kleinigkeit unterscheiden.

    Es kann in manchen Fällen die beste Lösung sein. So ist das nunmal, auch wenn es vielleicht nicht in ein wunderschönes Weltbild in dem es nur positive Variabilität gibt hineinpaßt. Natürlich ist das kein Normalfall, aber es ist durchaus möglich und dieses absolute "klare Sache, das muß ein Designfehler sein" wollte ich so nicht stehen lassen.

    Vielleicht kannst Du James O. Coplien aber auch mal ne eMail schreiben, daß die Lösung so einfach ist und auch fragen, warum er dann ein Buch geschrieben hat in dem sowas behandelt wird. 😉



  • Hi,

    ich weiß nicht, warum Du unbedingt einen Konflikt zwischen uns konstruieren willst. In NICHTS widersprichst Du mir inhaltlich und ich nicht Dir.

    So what's the point ? 😕

    Eigentlich würde mich mehr interessieren, wie es mit bluehart nun eigentlich weitergegangen ist.

    Gruß,

    Simon2.



  • Ich sehe durchaus einen Unterschied zwischen dem was Du schreibst und dem was ich schreibe. Aber wenn das für Dich gleich ist soll mir das auch recht sein. 🙂



  • 👍 peace 👍 😋

    Gruß,

    Simon2.



  • Nachdem wieder alles hier PEACE ist 😃 habe ich noch zwei Vorschläge.
    Würde zwar das Design was ändern aber was solls ...

    class RealA
    {
    public:
       // Ohne eine berechneBla-Funktion für Klassen die die Func nicht benötigen
    };
    
    class A : public RealA
    {
    public:  // Hier mit berechneBla(...)
      virtual float berechneBla(double, double);
    };
    
    class B : public A
    {
    public
      virual float berechneBla(double, double);
    };
    
    class C : public RealA
    {
    public:
       ...
    };
    

    Wenns wirklich nur drei Klassen sind dann könnte man es ja auch einfach so machen. Wenn eine Klasse wirklich nicht die Funktion braucht, dann halt eben nicht in die Basisklasse packen ...
    (Auch wenn das jetzt nicht vielleicht schön ist, aber ich weiß ja nicht was die Klassen in Wirklichkeit darstellen sollen)

    class A {
        public: 
                ...
    };
    
    class B : public A
    {
    public
      float berechneBla(double, double);
    };
    
    class C : public A
    {
    public:
       ...
    };
    

    Alles IMHO schöner als irgendwelche Exceptions.
    (Und jetzt kommt Simon2 und sagt mir was nicht schön ist 🙂 )

    Edit->Egal()

    blueheart schrieb:

    An der Klassenhierachie wollte ich so nichts ändern.

    Upps es jetzt gesehen, aber egal 😉



  • Simon2 schrieb:

    Hier entwirft gerade offensichtlich ein noch nicht besonders erfahrener C++-Programmierer (ist nicht böse gemeint, sind wir alle letztlich) ein Programm und ihm kommt zur Lösung seines Problems die "offensichtliche Lösung" in den Sinn.

    Ja, ja es ist wohl wirklich sehr offensichtlich. Ich fange gerade mit meinem ersten größeren Projekt an. Da hat es anfangs so an ziemlich allem gehapert. Aber ich gebe mir Mühe das auch wirklich alles zu verstehen und um besten umzusetzen.
    Allerdings muss ich zu dem Design sagen, dass das so vorgegeben ist. Also es sollen alle Objekte folgendenmaßen erschaffen werden:
    A * einer = new B;
    oder
    A * nocheiner = new C;

    Simon2 schrieb:

    Eigentlich würde mich mehr interessieren, wie es mit bluehart nun eigentlich weitergegangen ist.

    Ich habe mich nun erstmal dazu entschieden, in der Klasse die die Methode nicht verwendet, die Methode erst gar nicht hineinzuschreiben. In der Basisklasse A arbeite ich nun mit einer leeren Anweisungsliste. Wobei ich hier, eigentlich einen Wert zurückgeben müßte, da es sich ja nicht um eine void Methode handelt.
    -> Warnmeldungen von Compiler vorprogrammiert. -> also wahnsinnig schlechte Idee. Aber zumindest passiert so während der Laufzeit einfach gar nichts, wenn ein Objekt die Methode aufruft.
    Ich finde es schon sehr interessant, was ich hier für eine Diskussion ausgelöst habe. Ich habe auch die anderen Ideen mal ausprobiert.
    Gut Ding braucht Weile 🙂

    Schöne Grüße an alle



  • Freak_Coder schrieb:

    ...
    (Und jetzt kommt Simon2 und sagt mir was nicht schön ist 🙂 )
    ...

    Im Gegenteil: Jetzt kommt Simon2 und sagt, dass er das sehr schön findet. 😃

    Gruß,

    Simon2.



  • blueheart schrieb:

    ...Allerdings muss ich zu dem Design sagen, dass das so vorgegeben ist....

    Tja, sowas gehört eben so der "schmutzigen Realität". 😉

    blueheart schrieb:

    ...Ich fange gerade mit meinem ersten größeren Projekt an....

    Ich muß aber schon sagen, dass Du Dich sehr wacker schlägst und gründliche Gedanken machst - mit Deinen Fragen/Problemen schlagen sich so manche Leute noch beim 5. größeren Projekt rum 😃

    Schön, dass Du einen Weg für Dich gefunden hast.

    Liebe Grüße,

    Simon2.



  • phlox81 schrieb:

    Spacelord schrieb:

    Auf das Problem stößt man schneller als du denkst.
    Schau dir z.B. mal das Kompositum Pattern an.Da sind auch alle Objekte Komponenten....aber Blätter können keine Kinder haben und somit auch keine sinnvolle Implementierung der entsprechenden Methoden bieten.
    Somit wäre ja eines der "wichtigsten" Design Patterns ein Designfehler?

    Gruß Spacelord

    Nein, die Komposition leitest du von einer Basisklasse ab, welche nur die für Blatt benötigten Methoden besitzt.
    Siehe auch http://de.wikipedia.org/wiki/Kompositum_(Entwurfsmuster)

    Sorry,aber das ist Quatsch.
    Wenn du schon den Wikipedialink postest solltest du diesen eventuell auch selber lesen.
    Abgesehen davon ist die Geschichte im GoF Buch ebenfalls so aufgeführt.

    Wikipedia schrieb:

    Bestandteile

    Die Komponente definiert als Basisklasse das gemeinsame Verhalten aller Teilnehmer. Sie ist im Allgemeinen abstrakt und zum Beispiel ein Verzeichniseintrag.

    Das Blatt repräsentiert ein Einzelobjekt, es besitzt keine Kindobjekte und ist zum Beispiel in einem Dateiverzeichnis eine Datei.

    Das Kompositum enthält Komponenten, also weitere Komposita oder auch Blätter, als Kindobjekte und repräsentiert zum Beispiel ein Verzeichnis

    Gruß Spacelord


Anmelden zum Antworten