Welche pure virtual Methoden muss man implementieren?
-
Artchi schrieb:
die Methode in der Basisklasse ist sowohl Abstract als AUCH implementiert!
Beweise.
Devil
-
Also bis jetzt sehe ich keine Antwort auf die Frage, deshalb bleibe ich bei meiner Theorie.
-
Wie "Beweise"? Ich sage das ja nicht! Das sagt Volkard! Er hat doch gesagt, das jemand, der mit GUI-Programmierung anfängt, kein solches Beispiel liefern kann (welches auch ich NICHT kenne, wie oben von mir bereits gesagt). Dann hat SideWinder hier gefragt, ob jemand ein Beispiel liefern kann. Ich kenne keines, wie es Volkard fordert. Ich kenne nur mein oben gebrachtes Beispiel.
Letztendlich weiß es hier anscheinend keiner. Ich will dir nur sagen, das was du und ich als Beispiele gebracht haben, nicht das ist, was Volkard will. Alles klar?
-
lol!
ihr habt echt zu vel am farbtopf geschnuppert.den pur virtuellen basisklassendestruktor MUSS man implemetieren, denn er WIRD (vom abgeleiteten destruktor) aufgerufen.
-
volkard schrieb:
lol!
ihr habt echt zu vel am farbtopf geschnuppert.den pur virtuellen basisklassendestruktor MUSS man implemetieren, denn er WIRD (vom abgeleiteten destruktor) aufgerufen.
Jetzt hätte ich dafür gerne ein sinnvolles Beispiel, damit es auch alle verstehen
Devil
-
Strogij schrieb:
pure virtual meine ich natürlich, eine abstrakte Klasse muss also auch wie jede andere einen Konstr,Destr,Zuweis,Kopie haben (evtl. macht das der Compiler).
Die drei anderen, Konstruktor, Koperkonstruktor und Zuweisungsoperator wirste nicht virtuell hinkriegen. Das hatte sowenig mit pur virtuell zu tun, daß keiner mehr auf deinen richtigen Teilvorschlag mit dem Destruktor einging.
Gehe ich recht in der Annhame, daß Du noch nicht GUI programmerst?
-
volkard schrieb:
lol!
ihr habt echt zu vel am farbtopf geschnuppert.den pur virtuellen basisklassendestruktor MUSS man implemetieren, denn er WIRD (vom abgeleiteten destruktor) aufgerufen.
Ich möchte das jetzt so vorsichtig wie nur irgendmöglich ausdrücken:
Ich finde diese Frage nicht geeignetm um zu prüfen, ob jemand OOP verstanden hat.
-
devil81 schrieb:
Jetzt hätte ich dafür gerne ein sinnvolles Beispiel, damit es auch alle verstehen
If the class should be abstract (you want to prevent instantiating it) but it doesn't happen to have any other pure virtual functions, a common technique to make the destructor pure virtual.
http://www.gotw.ca/gotw/031.htm
reicht es, wenn sutter "common techniqe" sagt?
-
Optimizer schrieb:
Ich finde diese Frage nicht geeignetm um zu prüfen, ob jemand OOP verstanden hat.
nö. egentlich kann man GUI doch viel früher anfangen. mit JAVA! da macht man die schublade mit OO-sachen weit auf und holt sich einfach raus, was man haben mag. und da hat man OO auch schnell verstanden.
in c++ geht das nicht. man kann nicht sofort gut c++, wenn man gut OO kann. zu c++ gehört viel handwerkszeug. und man kann auch ein sehr guter c++-programmierer sein, ohne zu wissen, daß pur virtuelle destruktoren implementiert sein müssen. aber ich möchte es mal so sagen: es ist gelinde gesagt nicht extrem wahrscheinlich. irgendwo wirds dann schon an erfahrung oder belesenheit noch ein wenig mageln.
das beispiel war eigentlich tief aus der grundlagenschublade, das müßt ihr zugeben. ihr hattet alle zutaten. aber die praxis fehlt. und meist endet die grundlagenausbildung recht aprupt, wenn GUI anfängt und man macht erstmal zwei bis fünf jahre nur noch farben statt inhalten.
bei GUI in c++ sollte man sehr sicher mit OO (mit "wie mache ich OO mit c++") und so sein, denn die GUI-libs sind allesamt scheußlich designed. wenn man sich da was abguckt, kriegt der eigene code sofort pest und cholera zugleich.das "wie mache ich OO mit c++" ist weit mehr als nur OO, man denke an templates, mehrfache erblichkeit, rtti, RAII, exceptions, exceptionsicherheit, placement new, templates als basisklassen, ein wenig metaprogrammierung und so sachen, die man alle miteinander in ner guten lib einsetzen wird. und die selten in mickey-maus-sprachen zu finden sind.
im ursprungsthread schrieb ich "mindestens ein jahr nur konsole. zu frühes gui-proggen ist in c++ der sichere weg in die stümperschaft." warum wohl schrieb ich das "in c++" da rein? es war im kontext doch eh klar, daß es um c++ geht. weil es eher nur in c++ so schlimm ist, zu früh gui zu proggen. nicht in anderen sprachen. die anderen haben ne weniger selbstmörderische sprache und haben bessere bibliotheken. ich schreib weiterhin "mach erst gui, wenn du sachen wie vererbung sicher beherrscht, wenn du zum beispiel nicht mehr drüber nachdenken mußt, warum es pur virtuelle methoden gibt, die implementiert werden müssen". das war ne aufzählung. vererbung und so muß drin sein. und zum beispiel... sollte drin sein. oder andere beispiele halt. so in dieser liga sollte man langsam sicher werden, davor isses einfach schlecht.
-
volkard schrieb:
Die drei anderen, Konstruktor, Koperkonstruktor und Zuweisungsoperator wirste nicht virtuell hinkriegen. Das hatte sowenig mit pur virtuell zu tun, daß keiner mehr auf deinen richtigen Teilvorschlag mit dem Destruktor einging.
Gehe ich recht in der Annhame, daß Du noch nicht GUI programmerst?Naja da habe ich mich wohl geirrt, also ist nur der pure-vurtueller Destruktor Pflicht für eine Implementation. Weil er den Base-Konstruktor zuerst aufrufen muss, bevor er an seinen eigenen rangeht. Jetzt gebe ich zu - die drei anderen zu erwähnen war Quatsch.
Mit GUI programmiere ich nicht.
-
Optimizer schrieb:
volkard schrieb:
lol!
ihr habt echt zu vel am farbtopf geschnuppert.den pur virtuellen basisklassendestruktor MUSS man implemetieren, denn er WIRD (vom abgeleiteten destruktor) aufgerufen.
Ich möchte das jetzt so vorsichtig wie nur irgendmöglich ausdrücken:
Ich finde diese Frage nicht geeignetm um zu prüfen, ob jemand OOP verstanden hat.<streitheraufbeschwör>
Sehe ich genauso.
</streitheraufbeschwör>
-
breaktogether schrieb:
<streitheraufbeschwör>
Sehe ich genauso.
</streitheraufbeschwör>ich auch.
-
das beispiel war eigentlich tief aus der grundlagenschublade, das müßt ihr zugeben. ihr hattet alle zutaten. aber die praxis fehlt. und meist endet die grundlagenausbildung recht aprupt, wenn GUI anfängt und man macht erstmal zwei bis fünf jahre nur noch farben statt inhalten.
Ach und wann macht ein pure virtueller Destruktor in einem Interface Sinn? Ein virtueler ja und den implementiere ich immer gleich mit ~Foo(){}.
den pur virtuellen basisklassendestruktor MUSS man implemetieren, denn er WIRD (vom abgeleiteten destruktor) aufgerufen
Du wirst wahrscheinlich geschockt sein aber es gibt Compiler die fals es kein Basisklassendestruktor gibt davon ausgehen, dass die Basisklasse keinen brauch und ihn einfach nicht aufrufen! Und da du wie du in einen anderen Threat bereits gesagt hast nicht so sehr auf den Standard achtest ist diese kleine Verletzung ja wohl kein Problem oder?
bei GUI in c++ sollte man sehr sicher mit OO (mit "wie mache ich OO mit c++") und so sein, denn die GUI-libs sind allesamt scheußlich designed. wenn man sich da was abguckt, kriegt der eigene code sofort pest und cholera zugleich.
Wie wahr, wie wahr. Aber was gibt es für Alternativen? Ein Unendlichkeit und einen Tag darauf verwenden die "prefekte" Wrapper lib zu coden und an jeden Unwahrscheinlichkeit gedacht zu haben um dann fest zustellen, dass man der einzige ist der seinen Code noch verstehen kann und dann in ein kleines Problem läuft, an das man nicht beim designen nicht gedacht hatte, und dann Stunden darauf verwendet eine Elegante Lösung zu finden. Dann stellt man fest, dass die Lösung die von der Sprache vorgeschlagen ist unelegant ist und versucht mit Preprocessor instruction der Sprache seinen eigenen Syntax aufzubrummen. Und wenn endlich mit dem Design fertig ist ist man reif für die Rente.
Gutes Design ist etwas wertvolles aber vergiss nicht ein Program ist dazu da zu laufen und nicht um gut designed zu sein.
-
Ach und wann macht ein pure virtueller Destruktor in einem Interface Sinn?
wer sagt, daß er "in einem interface" sinn machen muß? vestehst du "interface" so, wie
die java-leute?
in c++ macht er dann sinn, wenn man eine klasse abstrakt machen will (und das ist ne
inhaltliche entscheidung), aber keine andere methode reinstopfen will (wieder inhaltlich).Du wirst wahrscheinlich geschockt sein aber es gibt Compiler die fals es kein Basisklassendestruktor gibt davon ausgehen, dass die Basisklasse keinen brauch und ihn einfach nicht aufrufen! Und da du wie du in einen anderen Threat bereits gesagt hast nicht so sehr auf den Standard achtest ist diese kleine Verletzung ja wohl kein Problem oder?
dann geb ich der basisklasse halt ein member mit dtor, nen string. dann hat die basisklasse
wohl nen dtor, der aufgerufen werden muss.
und das passiert auch ganz leicht:class Vogel{//Vogel muss abstrakt sein string name; public: Vogel(string _name): name(_name){ } virtual ~Vogel(){ } string const& getName(){ return name; } virtual void flieg()=0; }; class Singvogel{ ... virtual void flieg=0; void flieg(){//biete standard-impl an cout<<"Flatter flatter"<<endl; } }; class Amsel{ ... virtual void flieg(){ Singvogel:flieg();//nehme standard-impl an, ist bewußte entscheidung und nicht ein versehen } };
soweit ist doch alles ok. ich erzwinge, daß jeder vogel einen gültigen namen hat. vogel ist abstrakt. aber jetzt kömmts: der chef kommt auf die schnapsidee, daß pinguine auch vögel seien und besteht darauf!
also weg mit flieg()! zwischen Vogel und SIngvogel wird schnell ne klasse FliegeVogel reingefummelt, die flieg() trägt. Vögel selbst könen erstmal gar nix gemeinsames, außer
in gemeinamen listen verwaltet werden. VOGEL MUSS ABER ABSTRAKT SEIN. was tun?Wie wahr, wie wahr. Aber was gibt es für Alternativen? Ein Unendlichkeit und einen Tag darauf verwenden die "prefekte" Wrapper lib zu coden und an jeden Unwahrscheinlichkeit gedacht zu haben um dann fest zustellen, dass man der einzige ist der seinen Code noch verstehen kann und dann in ein kleines Problem läuft, an das man nicht beim designen nicht gedacht hatte, und dann Stunden darauf verwendet eine Elegante Lösung zu finden. Dann stellt man fest, dass die Lösung die von der Sprache vorgeschlagen ist unelegant ist und versucht mit Preprocessor instruction der Sprache seinen eigenen Syntax aufzubrummen. Und wenn endlich mit dem Design fertig ist ist man reif für die Rente.
nein, das sollten nur die wenigsten machen. der präprozessor ist eh nur, um erfahrungen zu sammeln und es muss mal ein voller compiler werden.
aber sagte ich, dass man zuerst ne zeit lang mit konsole üben muss, damit man später perfekte wraper baut? nee, darum gehts nicht. es geht darum, daß man nicht trennen kann, zwischen totaler scheiße, was alles um die gui betrifft und totaler eleganz, was sein eigenes modell betrifft. man hat den werkzeugkasten noch nicht voll genug, daß man zu den meisten problemchen auch ein paar lösungen hätte. man guckt bei der guzi ab, wie die es lösen. prompt hat man lauter klassen mit default-konstruktor (obwohl ein socket, der nicht connected ist, schwachfug ist), lauter delete this (ja, manche windows löschen sich magisch alleine beim schließen) und weitere 1000 verbrechen kannste selber schnell finden. leider alles sachen, die für den nube nicht offensichtlich schlecht sind, sodaß er sich sowas durchaus erstmal angewöhnt. und solche angewohnheiten werden auf seiner weiteren suche nach lösunen natürlich alle seine bewertungen verbiegen. ein teufelkreis, aus dem er nicht so leicht rauskommt. es wird jahre vergeuden.Gutes Design ist etwas wertvolles aber vergiss nicht ein Program ist dazu da zu laufen und nicht um gut designed zu sein.
...sagt der buchhalter zum mathematiker.
-
wer sagt, daß er "in einem interface" sinn machen muß? vestehst du "interface" so, wie
die java-leute?Ich habe nie in Java geproged also kann ich das nicht sagen, aber mit einer pur virtualen Methode sagst du ja, dass es sie geben muss und, dass zu faul zum implementieren bist oder sie aus irgend einem Grund nicht implementieren kann (wobei letzteres oft eine Ausrede ist).
in c++ macht er dann sinn, wenn man eine klasse abstrakt machen will (und das ist ne
inhaltliche entscheidung), aber keine andere methode reinstopfen will (wieder inhaltlich).Ich proge zwar noch nicht so lange mit pure virtuelen Methoden aber mir ist noch kein Fall begegnet wo eine Klasse abstrakt sein muss wenn es keinen geeignete Methode gibt. Ein leeres/nichstuendes Object ist nutzlos, aber wieso sollte man verbieten was nutzlos ist solange es nicht falsch ist?
Unter einem Interface verstehe ich sowas:
class A{ public: virtual void foo()=0; virtual void foo2(int)=0; virtual char foo3()=0; virtual void foo4(short)=0; virtual ~A(){} };
dann geb ich der basisklasse halt ein member mit dtor, nen string. dann hat die basisklasse
wohl nen dtor, der aufgerufen werden muss.In dem Fall hat die Basisklasse ja einen Dtor der aufgerufen werden kann und wird
, dass der User ihn nicht expicit definiert hat tut nichts zur Sache, dass es ihn gibt.
aber sagte ich, dass man zuerst ne zeit lang mit konsole üben muss, damit man später perfekte wraper baut? nee, darum gehts nicht. es geht darum, daß man nicht trennen kann, zwischen totaler scheiße, was alles um die gui betrifft und totaler eleganz, was sein eigenes modell betrifft.
Naja ich hab zwar sehr schnell mit der WinAPI angefangen und ich kann eigentlich nicht sagen, dass es mir geschadet hätte. Seitdem verwende ich static_cast/reinterprete_cast anstat von C casts. Denn sowas:
int a=(++(*(int*)GetWindowLong(hwnd,GWL_USERDATA)));
Ist einfach nur grausam.
Da ist sowas schon besser
int*b=reinterpret_cast<int*>(GetWindowLong(hwnd,GWL_USERDATA)); *b+=1; int a=*b;
Allein durch die Länge der Wörter reinterpret_cast und static_cast kommt man gar nicht erst auf die Idee das alles in eine Zeile zu stopfen.
-
Irgendwer schrieb:
Ich proge zwar noch nicht so lange mit pure virtuelen Methoden aber mir ist noch kein Fall begegnet wo eine Klasse abstrakt sein muss wenn es keinen geeignete Methode gibt.
deswegen das Vogel-Beispiel.
Ein leeres/nichstuendes Object ist nutzlos, aber wieso sollte man verbieten was nutzlos ist solange es nicht falsch ist?
hilfe! um eigene denkfehler compilerfindbar zu machen! deswegen verbiete ich immer jeden copy-ctor und zuweisungsop und mache sie erst auf, wenn ich ne echte inhaltliche berechtigung sehe, wenn ich sehe, daß kopieren von dem kram nutzbringend ist.
und Vogel-objekte sind verboten, weil es kein objekt von typ Vogel geben darf. weil das sicher ein programmierfehler wäre. wenn ich ne klasse von programmierfehlern compilerfindbar machen kann, dirch ein läppisches "=0" an der richtigen stelle, dann soll ich das tun, oder?
oder eher in meiner welt: Vogel ist von der bedeutung her abstrakt, dann soll die klasse auch abstrakt sein.dann geb ich der basisklasse halt ein member mit dtor, nen string. dann hat die basisklasse
wohl nen dtor, der aufgerufen werden muss.In dem Fall hat die Basisklasse ja einen Dtor der aufgerufen werden kann und wird
, dass der User ihn nicht expicit definiert hat tut nichts zur Sache, dass es ihn gibt.
nee, falsch ausgedrückt.
dann muss die basisklasse nen dtor haben, der aufgrufen werden muss, wenigstens um das member zu löschen. indem ich nen dtor pur virtuell deklariere wird der automatische nicht mehr gebaut, sondern es wird erwartet, daß ich einen baue (in ner anderen übersetzungseinheit). wenn ich das ncht mache, gibts nen linkerfehler, weil ich diesen pur virtuellen dtor nicht implementiert habe.
-
Irgendwer schrieb:
int*b=reinterpret_cast<int*>(GetWindowLong(hwnd,GWL_USERDATA)); *b+=1; int a=*b;
jo, ist die richtige richtung. natürlich muss zuerst ein wrapper her.
inline LONG myGetWindowLong(HWND hWnd,int nIndex){ LONG r=GetWindowLong(hWnd,nIndex); if(!r) throw WindowsException(GetLastError); return r; }
das gewöhne man sich einfach für ALLE winapi-aufrufe an, und man muß im code nie mehr auf fehler prüfen.
aber das müßt ihr natürlich nicht, ihr könnt auch per hand gegen 0 testen, aber es zu vergessen wäre nicht extrem nett.die zeile
int*b=reinterpret_cast<int*>(GetWindowLong(hwnd,GWL_USERDATA));
darf zur not auch zerhackt werden, geschmackssache.
aber*b+=1;
war übertrieben. das ist nicht lesbarer oder in irgend einer weise besser als
++*b;
der leser deines codes hat c++ zu kennen. zu stark verhätscheln bringt auch nix.
-
das gewöhne man sich einfach für ALLE winapi-aufrufe an, und man muß im code nie mehr auf fehler prüfen.
aber das müßt ihr natürlich nicht, ihr könnt auch per hand gegen 0 testen, aber es zu vergessen wäre nicht extrem nett.Kaum zu glauben, aber MS hat es für .Net mal wirklich geschafft, mit Exceptions zu arbeiten.
-
Hmm, ich hab dauernd an irgendwelche Spezialmethoden gedacht, dass hier mit Methode auch ein Destruktor gemeint sein kann...
Ist übrigens interessant was manche Leute hier alles so gedichtet haben
MfG SideWinder
-
Ja, weil Volkard meiner Meinung nach rumgelabert hat, nach dem Motto "Ihr wisst eh nichts!". Da haben wir wie die dummen rumgeraten... Und es ist mir egal wieviel Posts er inne hat. Sooo doof sind wir nun auch wieder nicht, oder?