Exception werfen beim Aufruf einer virtuellen Methode



  • Mein Code sagt einfach, dass die Methode foo in der Klasse Derived ab jetzt privat ist 🙂



  • GPC schrieb:

    Mein Code sagt einfach, dass die Methode foo in der Klasse Derived ab jetzt privat ist 🙂

    Das funktioniert aber nur solange, wie nicht mit Basisklassen-Zeigern gearbeitet wird.

    bis bald
    akari



  • GPC schrieb:

    Mein Code sagt einfach, dass die Methode foo in der Klasse Derived ab jetzt privat ist 🙂

    Hmmm, aber verhindert das nicht nur den "statischen Aufruf" (also, wenn der statische Typ C ist) ?
    Ich glaube nicht, dass das gegen das o.g. Verhalten (via Basisklassen-Pointer) schützt.

    Edith: 2l8 !!

    Gruß,

    Simon2.



  • Err, jupp. Aber von Basisklassenzeigern sprach bisher auch noch niemand 😉 :p

    Simon2 schrieb:

    Edith: 2l8 !!

    Grüß Edith von mir 😉



  • GPC|off schrieb:

    ...Aber von Basisklassenzeigern sprach bisher auch noch niemand 😉 :p

    Nanana:

    ser1al schrieb:

    ...

    ...
     base* p = new base;
    ...
    

    und ehrlich gesagt: Wer macht schon Polymorphie anders ? :p

    GPC|off schrieb:

    ...
    Grüß Edith von mir 😉

    Gruß zurück 😃

    Gruß,

    Simon2.



  • tja, eigentlich wollte ich mit den Objekten der Klasse B und C arbeiten.

    Aber mein Kopf will irgendwie nicht mehr an eine richtige Lösung glauben.
    (immer diese Fehlermeldungen 😉 )
    Trotzdem mit eurer hilfe werde ich es wohl doch vielleicht noch hinbekommen.

    Werde denn mal zum schluss meine lösung dazu posten



  • Simon2 schrieb:

    GPC|off schrieb:

    ...Aber von Basisklassenzeigern sprach bisher auch noch niemand 😉 :p

    Nanana:

    ser1al schrieb:

    ...
    [cpp]
    ...
    base* p = new base;
    ...

    Oha, richtig. ser1als Code hatte ich nur überflogen.

    und ehrlich gesagt: Wer macht schon Polymorphie anders ? :p

    klaro, ihr habt ja auch recht. Dennoch find ich den Exception Ansatz nicht wirklich toll... Während man halt so mit dem Programm arbeitet, poppt ne MessageBox hoch: "Boink. Der Programmierer hat eine Methode verwendet, die er nicht verwenden darf, ich mach Feierabend." ^^

    Grüße

    GPC



  • Tja, wenn Du uns Deine Probleme nicht mitteilst, wirst Du wohl nie zu einer funktionierenden Lösung kommen (auch wenn es sie gibt, und eigentlich sehr trivial ist sowie hier schonmal gepostet wurde).



  • GPC schrieb:

    ...Dennoch find ich den Exception Ansatz nicht wirklich toll...

    Dem stimme ich uneingeschränkt zu.

    blueheart schrieb:

    ...mein Kopf will irgendwie nicht mehr an eine richtige Lösung glauben....

    Das (und GPCs Bauchschmerzen) wird vermutlich daran liegen, dass Du "unsauber designt hast". Wenn B und C von A erben, heißt das, dass sie beide "ein A sind".
    Wenn dann A eine virtuelle Funktion f() hat, heißt dass das "jedes A auch f() kann".
    Da nun "jedes C ein A ist", und "jedes A f() kann" => "C kann f()".

    Wenn Du nun zu dem Schluß kommst, C soll "f() nicht können", hast Du irgendwo einen Denkfehler gemacht. Entweder "kann nicht jedes A f()" oder "C ist kein A"....

    Denk' Dir das nochmal durch.

    Gruß,

    Simon2.



  • Wenn in A die Methode pure virtual ist, müsste es doch mit dem Verschieben
    der Methode in den private Bereich klappen, oder?



  • phlox81 schrieb:

    Wenn in A die Methode pure virtual ist, müsste es doch mit dem Verschieben
    der Methode in den private Bereich klappen, oder?

    Das Problem ist eher, dass wir hier von Laufzeitpolymorphie sprechen. Und der kann man leider weder mit Compilezeit- (und dazu zählt die Zugriffskontrolle via private) noch mit Linkzeit-sicherungsmechanismen (wie einer undefinierten pure virtual function) sinnvoll beikommen.
    Erst zur Laufzeit entscheidet sich, ob der Basisklassenpointer auf ein B oder ein C zeigt...

    Gruß,

    Simon2.



  • GPC schrieb:

    Simon2 schrieb:

    GPC|off schrieb:

    ...Aber von Basisklassenzeigern sprach bisher auch noch niemand 😉 :p

    Nanana:

    ser1al schrieb:

    ...
    [cpp]
    ...
    base* p = new base;
    ...

    Oha, richtig. ser1als Code hatte ich nur überflogen.

    Grüße

    GPC

    hehe, eigentli wollte ich da member schrieben 🙄

    Simon2 schrieb:

    GPC schrieb:

    ...Dennoch find ich den Exception Ansatz nicht wirklich toll...

    Dem stimme ich uneingeschränkt zu.

    Gruß,

    Simon2.

    und das habe ich ja auch gesagt, das ich den stil nicht gut finde...dennoch wollte ich ihm sagen das es schon funktioniert!



  • Simon2 schrieb:

    phlox81 schrieb:

    Wenn in A die Methode pure virtual ist, müsste es doch mit dem Verschieben
    der Methode in den private Bereich klappen, oder?

    Das Problem ist eher, dass wir hier von Laufzeitpolymorphie sprechen. Und der kann man leider weder mit Compilezeit- (und dazu zählt die Zugriffskontrolle via private) noch mit Linkzeit-sicherungsmechanismen (wie einer undefinierten pure virtual function) sinnvoll beikommen.
    Erst zur Laufzeit entscheidet sich, ob der Basisklassenpointer auf ein B oder ein C zeigt...

    Gruß,

    Simon2.

    hm, stimmt...

    Dann bleibt nur die Exception, oder in B eine leere Methode implementieren, der Aufruf tut dann nix.



  • phlox81 schrieb:

    ...in B eine leere Methode implementieren, der Aufruf tut dann nix.

    Ist nicht wirklich besser - nur eine andere Form vom "broken contract" 😉 (dann schon lieber eine exception; da hat der Anwender zwar die AKarte gezogen, aber immerhin merkt irgendjemand, dass unerwünschtes Verhalten vorliegt).

    Aber wie gesagt: Ich denke, dass hier einfach ein Designfehler vorliegt, den es zu beheben gilt.

    Gruß,

    Simon2.



  • Wieso nicht einfach in C die Methode Nicht definieren.
    Jeder Aufruf würde dann zu einem Linker-Error führen ...



  • Freak_Coder schrieb:

    Wieso nicht einfach in C die Methode Nicht definieren.
    Jeder Aufruf würde dann zu einem Linker-Error führen ...

    Wie gesagt: Weils nicht klappt. 😉
    Einerseits kann es der Linker gar keinen Fehler feststellen (ein entsprechender Aufruf würde mir A::f() verbunden), andererseits kann der Linker nicht feststellen, was erst zur Laufzeit feststeht.

    Gruß,

    Simon2.



  • Während man halt so mit dem Programm arbeitet, poppt ne MessageBox hoch: "Boink. Der Programmierer hat eine Methode verwendet, die er nicht verwenden darf, ich mach Feierabend." ^^

    Hehe ich stell mir das grade mit so einem Programm wie Word oder PaintshopPro vor 😃



  • DEvent schrieb:

    Hehe ich stell mir das grade mit so einem Programm wie Word oder PaintshopPro vor 😃

    Wäre allemal aufschlussreicher als "OpenOffice.exe hat ein Problem verursacht und muss beendet werden. Möchten Sie einen Problembericht an Microsoft senden?" 😃



  • Simon2 schrieb:

    GPC schrieb:

    ...Dennoch find ich den Exception Ansatz nicht wirklich toll...

    Dem stimme ich uneingeschränkt zu.

    blueheart schrieb:

    ...mein Kopf will irgendwie nicht mehr an eine richtige Lösung glauben....

    Das (und GPCs Bauchschmerzen) wird vermutlich daran liegen, dass Du "unsauber designt hast". Wenn B und C von A erben, heißt das, dass sie beide "ein A sind".
    Wenn dann A eine virtuelle Funktion f() hat, heißt dass das "jedes A auch f() kann".
    Da nun "jedes C ein A ist", und "jedes A f() kann" => "C kann f()".

    Wenn Du nun zu dem Schluß kommst, C soll "f() nicht können", hast Du irgendwo einen Denkfehler gemacht. Entweder "kann nicht jedes A f()" oder "C ist kein A"....

    Denk' Dir das nochmal durch.

    Gruß,

    Simon2.

    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



  • 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)


Anmelden zum Antworten