Casting-Arten für z.B. Pointers
-
Hallo
wenn man einen gegeben Pointer 'ptr' in einen anderen Pointertyp umwandeln möchte, dann könnte man das folgendermassen machen:
MeineKlasse* pClassPtr = NULL; pClassPtr = (MeineKlasse*) ptr;Nun habe ich mal Code gesehen, bei welchem es so gemacht wird:
MeineKlasse* pClassPtr = NULL; reinterpret_cast<MeineKlasse*>(ptr);Die MSDN meint zu Letzterem, dass es höchst unsicher sei. Na ok, aber das wird's bei der 1. Version oben wohl auch so sein.
Frage: Welche dieser Möglichkeiten wird gemäss den 'best practices' eher verwendet? (wenn überhaupt)
Aja, gibt es eigentlich eine Möglichkeit zu prüfen, ob ein Pointer von einem bestimmten Typ ist?
In Java kann man herausfinden, um welchen Klassentyp es sich dabei handelt.
C++ kennt angeblich auch so etwas, aber jene Methode die ich damals gefunden hab, konnte man nur in bestimmten Situationen verwenden.Thanks for any good comments

-
Du kannst einen Pointer umwandeln mit static_cast wenn du weißt was für ein Typ es ist und wenn man den Pointer in den Zieltyp umwandeln kann.
Mit reinterpret_cast umgehst du jegliche Typsicherheit, da diese Umwandlung wie der Name schon sagt, die Bytes einfach neu interpretiert.Das was du in deinem letzten Absatz ansprichst ist dynamic_cast damit kannst du zB ein Basisklassenobjek in ein Objekt einer abgeleiteten Klasse umwandeln, das geschieht im Gegensatz zu den anderen casting Typen zur Laufzeit und kann auch fehlschlagen. Am besten ist wohl nen Beispiel:
struct Base{}; struct Derived : Base{}; void bar( const Base* obj ) { if( ( Derived* myDerived = dynamic_cast< Derived* >( obj ) ) != 0 ) cout << "Es ist ein Derived Objekt" << endl; if( ( Base* myBase = dynamic_cast< Base* >( obj ) ) != 0 ) cout << "Es ist ein Base Objekt" << endl; } int main () { Base* base = new Base; Base* derBase = new Derived; Derived* der = new Derived; bar( base ); bar( derBase ); bar( der ); // zu faul für die deletes }
-
sky21 schrieb:
wenn man einen gegeben Pointer 'ptr' in einen anderen Pointertyp umwandeln möchte, dann könnte man das folgendermassen machen:
MeineKlasse* pClassPtr = NULL; pClassPtr = ptr;Das geht aber nur, wenn ptr ein Zeiger auf eine von MeineKlasse abgeleitete Klasse ist (oder selbst auf MeineKlasse, aber das wär dann nicht wirklich eine Typ-"Umwandlung")
Nun habe ich mal Code gesehen, bei welchem es so gemacht wird:
MeineKlasse* pClassPtr = NULL; reinterpret_cast<MeineKlasse*>(ptr);Die MSDN meint zu Letzterem, dass es höchst unsicher sei. Na ok, aber das wird's bei der 1. Version oben wohl auch so sein.
Der reinterpret_cast funktioniert aber auch dann, wenn die Typen nicht zueinander passen. Das einfache zuweisen wie oben funktioniert ja eben nur in sehr sehr speziellen Fällen.
Frage: Welche dieser Möglichkeiten wird gemäss den 'best practices' eher verwendet? (wenn überhaupt)
Die sicherste, die möglich ist. Schau dir die ganzen Cast-Operatoren mal an (static_cast, dynamic_cast, reinterpret_cast, const_cast).
Aja, gibt es eigentlich eine Möglichkeit zu prüfen, ob ein Pointer von einem bestimmten Typ ist?
Ich nehm an, du meinst eine Laufzeitprüfung. Schau dir RTTI an (dynamic_cast, typeid). Das funktioniert aber nur bei polymorphen Typen, also Klassen, die mindestens eine virtuelle Memberfunktion enthalten.
-
Kommt drauf an wenn du den Cast wirklich erzwingen musst (wie z.B. von char* auf int*) dann brauchst du reinterpret_cast<>. Bei Polymorphie gehts mit dynamic_cast<>:
class Foo { }; class Bar : public Foo { void go() { cout << "I'm Bar::go()" << endl; }; Foo* pFoo = new Bar; Bar* pBar = dynamic_cast<Bar*>(pFoo); if(pBar) pBar->go();<edit>manman wieder zu langsam *hrhr*
-
FireFlow schrieb:
Kommt drauf an wenn du den Cast wirklich erzwingen musst (wie z.B. von char* auf int*) dann brauchst du reinterpret_cast<>. Bei Polymorphie gehts mit dynamic_cast<>:
Was allerdings nur beim downcasten sinnvoll ist, ansonsten reicht static_cast vollkommmen aus.
-
Für den Upcast braucht man keinen extra cast das geht automatisch...
-
Für den downcast reicht oftmals auch nen static_cast, der dynamic_cast ist nur dann notwendig, wenn man nicht sicher weiß, dass das Objekt 100%ig vom Typ x ist.
-
FireFlow schrieb:
Für den Upcast braucht man keinen extra cast das geht automatisch...
Hat ja auch niemand was anderes behauptet. Ich bezog vielmehr auf deine Aussage
FireFlow schrieb:
... wenn du den Cast wirklich erzwingen musst ...
-
Ein static_cast<> kann aber keine Pointer zu andern Pointern casten... Oder rede ich schon wieder von was anderem?
int * i = new int; char * c = static_cast<char*>(i); // BOOM! delete i;
-
FireFlow schrieb:
Ein static_cast<> kann aber keine Pointer zu andern Pointern casten...
Das stimmt so nicht ganz. Du kannst von und in void Zeiger casten.
FireFlow schrieb:
Oder rede ich schon wieder von was anderem?
Ja, das tust du. Wir hatten über Polymorphie gesprochen.