casts
-
1. kann ich folgendes irgendwie in einer zeile schreiben?
CBlah* Blah=(Blah*)BaseBlah;
Blah->func()//func gibts nur in CBlah, nich in CBaseBlah2. wie entscheide ich in der praxis welchen der verschiedenen casts ich verwenden soll, was sin die wichtigsten vorteile
3. gibts ne möglichkeit klassen scheibchenweise zu erstellen und zu löschen?
erst base, später hinzufügen von abgeleiteter zu base, dann löschen von abgeleiteter ohne löschen von base etc...
-
Hallo,
zu 1.
CBlah* Blah=dynamic_cast<CBlah *>(BaseBlah); if( Blah != NULL) { // tu irgendwas }
zu 2. sieh mal in den FAQs nach. Ich glaub da steht was über den Einsatz von casts. Ansonsten auch in jeden guten C++ Lehrbuch
Ach so, ich bin zwar kein Moderator, aber es gilt hier im Forum: eine Frage - ein Thread .
Ciao
-
deine antwort hat nix mit meiner frage zu tun
-
Sicher kannst du:
static_cast<CBlah*>(BaseBlah)->func();
Hat allerdings undefiniertes Verhalten, falls sich hinter dem Basisklassenzeiger BaseBlah nicht auch tatsächlich ein CBlah verbirgt. In dem Fall solltest du dir vielleicht doch mal die Lösung von Braunstein angucken.
-
gut danke
was braunsteins lösung angeht... ne ich trenn gern die prüfung von der ausführung damit nich son riesengewirr auf if abfragen rauskommtob das objekt ok is test ich vorher mit ner virtuellen funktion ->IsObjBlah()
-
Kann man machen. Hat man auch häufig, bevor es RTTI (Runtime Type Information) und damit dynamic_cast gab
-
damit hat sich wohl auch no.2 geklärt
static erzwingt den cast auch wenn müll rauskommt
dynamic erzeugt nen nullzeiger wenn das casten nich funzt
-
Wie wärs denn mit virtual T func() ohne cast ?
-
was meinst du mit "T"
prinzipiell nein... der namespace von baseblah soll einigermassen sauber bleiben
virtuell mach ich nur funktionen die sich alle abgeleiteten teilen
-
T soll für beliebigen Typ stehen....
(hätt ich void geschrieben und die gibt int zurück hatt ich das vor die Nase gehalten bekommen
Na, irgendwas ist in Deinem Design faul.
Erst sagst Du:
Mir ist es völlig egal von was für einem Typ Du bist.
Dann:
Was bist Du denn für einer ? Wenn Du X bist muss ich Y aufrufen udn wenn Du Z bist muss A aufgerufen werden.....Das passt nicht. Auch wenn ich jetzt was falsches sage, aber vllt. bringt Dich da noch das "Visitor Pattern" aus der Klemme. Details ka, habe es noch nie angewandt. AFAIK sollte es Dir hier aus der Klemme helfen. Ein Überdenken des Designs ist aber vllt. einfacher.
-
klemme?
ich bin in überhaupt keiner klemme
wollte nur wissen wie ich zwei zeilen auf eine verkürzwas mein design angeht
bei den basissachen isses mir egal
movie->play()
dvd->play()
audio->play()
wen interessiert das
lieber mediaobj->play()aber z.b. beim aufruf dvd->goto_menu() will ich natürlich schon wissen obs n dvd typ is
weiss noch jemand was zu punkt 3?
-
Bei allen Medien wird es ein Menü geben zu dem Du gehen musst.
Also:goto_menu() virtuell. Somit kann die DVD ihr eigenes Menu benutzten oder einer grundroutine einen Parameter mitgeben das sie eine DVD ist.
Dann hast Du:
a vorteile wenn ne brandNewMedia hinzukommt
b eine Zeile für den Aufruf (ohne cast)
-
ne mit goto_menu() mein ich das dvd menü... starte film,trailer,sprache etc...
anderes beispiel: goto_chapter()titel und kontextmenü ham damit nix zu tun...
also doch nich virtuell
-
Dann verstehe ich aber den wunsch nicht den cast in eine Zeile mit dem Aufruf zu bekommen. Denn das lässt mich persönlich darauf schliessen das Du eine allgemeine Routine hast die nun DVD spezifische dinge tun soll ?!
-
Sovok schrieb:
dynamic erzeugt nen nullzeiger wenn das casten nich funzt
Bei Zeigern. Bei Referenzen wirft es std::bad_cast. Sehr komfortabel, wenn du ziemlich sicher bist, dass das Objekt den richtigen Typ hat, ist also:
dynamic_cast<Blah&>(*zeigerAufBaseBlah).func();
Natürlich nur, wenn zeigerAufBaseBlah != 0 ist oder du sowieso eine Referenz hast.
-
hört sich praktisch an
wie handel ich sonen bad_cast throw denn richtig?
-
operator void schrieb:
Bei Zeigern. Bei Referenzen wirft es std::bad_cast. Sehr komfortabel, wenn du ziemlich sicher bist, dass das Objekt den richtigen Typ hat
«ziemlich»
Also entweder du bist dir sicher, und benutzt static_cast, oder du bist es nicht.</imho>
-
Sovok schrieb:
hört sich praktisch an
wie handel ich sonen bad_cast throw denn richtig?Wenn du ihn behandeln willst, also feststellen willst, ob das Objekte wirklich den richtigen Typ hat, per "try { code } catch(const std::bad_cast) { code }", also wie jede andere Exception auch. Insofern ist diese Variante nur hilfreich, um folgenden Code zu ersetzen, weil es dir das Werfen der Exception abnimmt:
Blah* blah = dynamic_cast<Blah*>(zeigerAufBaseBlah); if (blah == 0) throw IrgendeineException("zeigerAufBaseBlah hat nicht den Typ, den ich erwartet habe"); blah->func();
Wenn du im Falle, dass zeigerAufBaseBlah nicht auf ein Blah zeigt, etwas anderes tun willst, als eine Exception zu werfen (z.B. einfach gar nichts), ist die Version mit dynamic_cast<Blah*> einfacher.
Außerdem geht static_cast nicht überall, wo dynamic_cast geht, wenn Mehrfachvererbung ins Spiel kommt. Aber das ist hier wohl nicht der Fall.