Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

1

23.08.2004, 14:14

Casten

Hi,

ich habe eine Frage zu static_cast:

Ich bin mir nicht sicher ob die Funktionsweise wirklich verstehe.
Hier zwei Beispiele von Tests, die ich gemacht habe.

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
1. Konvertierung von float in int:
1.1 
float a = 1.0;
cout << (int)a << endl; // Ergebnis = 1

1.2
float a = 1.0;
cout << static_cast<int>(a) << endl; // Erbebnis = 1


2. Konvertierung von Zeigern
Ich habe eine Interface Klasse ITest und eine davon abgeleitete Klasse cTest. In cTest wird zusätlich zu den Interface Methoden eine Methode max() definiert.
2.1 
ITest *pTest = new cTest();
cout << (cTest*)pTest->max() << endl; // Fehler max nicht gefunden

2.2
ITest *pTest = new cTest();
cout << static_cast<cTest*>(pTest)->max() << endl; // OK


Fazit:
Ich seh das so das ich durch static_cast Typen konvertieren kann, bei primitiven Typen ist da kein Unterschiede zum "normalen" casten.
Bei Zeigern kann ich aber den "normalen" cast nicht verwenden und durch static_cast kann ich den Zeiger auf andere Typen setzten.

Stimmt das so?
Für was kann man static_cast noch gebrauchen?

Bei dynamic_cast auf Beispiel 2.2 kommt ein Laufzeitfehler:
__non_rtti_objec.
Damit kann ich auch nicht wirklich viel anfangen, ich weiss nicht wie ich das verhintern kann und was es Bedeutet.


Anmerkung:
Der Code oben ist sinnlos, sollte auch nur zum verdeutlichen des Problems benutzt werden.

DarthB

Treue Seele

Beiträge: 265

Beruf: Schüler

  • Private Nachricht senden

2

23.08.2004, 14:26

Hi,
ich habe zum casten von Zeigern immer "reinterpret_cast" benutzt. Soviel ich weiß ist er für solche Dinge auch da. Oder irre ich mich da?

Es wird wohl Unterschiede zwischen C-Casts und static_cast geben welche genau das sind weiß ich nicht. Bis jetzt habe ich auch noch keine bemerkt.

Aber hier im FAQ steht auch noch was dazu:
http://www.scherfgen-software.net/forum/viewtopic.php?t=662

Hoffe geholfen zu haben,
Ciao DarthB.

3

23.08.2004, 14:38

Hi, dankr für deine Antwort.

Ich vergesse immer erstmal in der FAQ zu kucken, tut mir echt Leid :angel:

So ganz beantwortet das meine Frage ja nicht, da ich ein konkretes Beispiel habe und jemand bräuchte der mir sagt, ob ich das so machen kann. Ob das so gemacht werden sollte und warum bei dynamic_cast ein __non_rtti_objec Fehler kommt.

Wegen dem Fehler, soweit ich weiss ist dynamic_cast ja typsicher im Gegensatz zu static_cast, aber ich weiss nicht wie ich den Fehler verhintern kann.

Auf jeden Fall danke für den FAQ Link und vielleicht hat ja noch jemand eine Antwort für mich :ohoh:

4

23.08.2004, 15:36

Der Fehler heißt "Das dein zu Castendes Objekt keine Runtime Type Informationen besitzt. Der dynamic_cast ist speziell für das Casten Klassen und Strukturen da. Das ganze hängt mit der Vererbung zusammen. Der dynamic_cast soll verhindern das man einen falschen Cast in der Vererbungshirarchie unternimmt.
Wichtig! Ich übernehme keinerlei Verantwortung für eventl. Datenverlust oder Schäden am Rechner ;D

5

23.08.2004, 15:43

Ok, also ich habe ja praktisch nur eine Interface Klasse und eine konkrete Klasse die davon erbt.
Erstellt habe ich ein Zeiger auf die Interface Klasse und habe versucht diesen in einen Zeiger auf die konkrete Klasse zu casten.

Ok, du hast Recht dreh ich die Geschichte um und versuche einen Zeiger auf eine konkrete Klasse in einen Zeiger auf die Interface Klasse zu casten, kommt kein Fehler.
Aber so was ist doch sinnlos? Andersherum würde es doch eher Sinn machen, weil ich so auch auf die speziellen Methoden in der konkreten Klasse zugreifen kann.... dachte ich zumindest :ohoh:

Also kann in praktisch von unten nach oben casten, aber nicht andersherum?!

Osram

Alter Hase

Beiträge: 889

Wohnort: Weissenthurm

Beruf: SW Entwickler

  • Private Nachricht senden

6

23.08.2004, 19:27

Hast Du mal statt

Quellcode

1
(cTest*)pTest->max() << endl; // Fehler max nicht gefunden


das hier versucht?:

Quellcode

1
((cTest*)pTest)->max() << endl;
"Games are algorithmic entertainment."

7

23.08.2004, 19:36

:ohoh: Ja du hast Recht, dass geht wirklich.
Ach verdammt, wieder mal scheisse geklammert.
Aber das entspricht ja dann im Prinzip dem static_cast, nur halt als C-Cast.

8

23.08.2004, 19:38

Um noch einmal zu den cast-Operatoren zurück zu kommen.

reinterpret_cast:
Dieser cast-Operator führt eine ungeprüfte Typenkonvertierung durch, die zur Compilerzeit ausgeführt wird. Es wird aber nicht Garantiert das das Ergbnis noch das selbe Bitmuster hat!

static_cast:
Dieser cast-Operator führt eine geprüfte Typenkonvertierung durch, die ebenfalls zur Compilerzeit ausgeführt wird. Es werden aber nur verwandte Typen konvertiert. Wie etwa zwischen zwei Zeigertypen einer Klassenhirarchie.

dynamic_cast:
Dieser cast-Operator führt eine geprüfte Typenkonvertierung durch, die zur Programmlaufzeit durchgeführt wird. Dementsprechend sind die Runtime Type Informations zwingend. Sonst kann der Operator die Konvertierung ja nicht prüfen ;) Der dynamic_cast ist also vergleicbar mit static_cast nur halt zur Prgrammlaufzeit.

[Zusammenfassung aus dem Buch "Die C++ Programmiersprache von Bjarne Stroustrup]

Zu deinem letzten Posting blueEye:
Man kann auch von dem Interface auf die Konkrete Klasse casten. Das ist möglich aber nicht empfehlenswert. Da nicht garantiert werden kann das dieser Zeiger dann auch die richtige Adresse hat. Dazu schaust du dir am besten einmal an wie die Vererbung im Adressraum bewerckstelligt wird. In vielen Fällen geht das gut. Vor allem wenn man als Basis nur eine abstrakte Klasse hat.

Sinnlos ist dies jedoch nicht. Denn
1) Bei einem Interface Design will man die eigentliche Funktionalität ja verstecken um sie austauschbar zu halten.

2) Bei Vererbung zwischen normalen Klassen (ohne Interfaces) ist die neue Klasse ja eine Weiterentwicklung von dessen Basisklasse. Wenn ich diese neuen Funktionen nicht brauche brauch ich ja auch nicht die neue Klasse erzeugen. Ich kann ja auch dessen Basisklasse erzeugen ;)
Wichtig! Ich übernehme keinerlei Verantwortung für eventl. Datenverlust oder Schäden am Rechner ;D

9

23.08.2004, 20:30

Ja Ok, dass klingt einleuchtend.

Damit wäre das Thema C++-Casts auch erledigt.

Danke für die schnelle Hilfe!

Werbeanzeige