Conversion von Dateitypen
-
Hi,
Ihr habt doch bestimmt bei Funktionen die etwas zurück geben schon mal so nen ähnlichen Warning bekommen, oder?
CObject(217): warning C4267: 'return' : conversion from 'size_t' to 'unsigned int', possible loss of data
nun jetzt gibt es ja 2 (mir bekannte :D)Möglichkeiten diesen Warning zu korregieren:
return unsigned(WERT); return (unsigned) WERT;
gibt es zwischen diesen beiden Methoden irgendeinen Unterschied außer die Schreibweise oder noch andere Unterschiede? Was wird von dem C++ Standard lieber gesehen, Methode A oder Methode B?
Viele Grüße,
Snoop
-
wenn dann
return static_cast<unsigned>(WERT);ist aber bloedsinn.
denn daten verlieren kannst du so auch!
warum gibt deine funktion nicht size_t zurueck wenn sie intern mit size_t arbeitet??
-
sie gibt diesen wert zurück weil die std::vector::size(); funktion size_t zurück gibt
-
dann lass doch deine funktion
std::vector<foo>::size_type
zurueck geben...
-
nun jetzt gibt es ja 2 (mir bekannte )Möglichkeiten diesen Warning zu korregieren:
return unsigned(WERT);
return (unsigned) WERT;
1. standard ctor
2. c cast ( nicht im c++ standard .. -> static_cast wie Shade beschrieben dagegen schon )
-
Also Methode 1? oder static_cast?
-
beides.
-
womit wir sicher sein können, daß "beides" eine schlechte antwort wäre.
-
1. standard ctor
Nö. Mit Standard-Ctor hat das nichts zu tun.
Diese explizite Typkonvertierung in der sogenannten "functional notation" ist in diesem Fall gleichbedeutend mit dem entsprechenden cast. Das wäre in diesem Fall der static_cast. Demzufolge ist:return unsigned(Wert);
von der Bedeutung her äquivalent zu:
return static_cast<unsigned>(Wert);
[ Dieser Beitrag wurde am 27.06.2003 um 11:56 Uhr von HumeSikkins editiert. ]
-
Original erstellt von 1ntrud0r:
2. c cast ( nicht im c++ standard .. -> static_cast wie Shade beschrieben dagegen schon )Just for the records (Hume hat das implizit schon gesagt): Natürlich ist das Ding in der C++-Norm zu finden.
-
Original erstellt von Shade Of Mine:
dann lass doch deine funktion
std::vector<foo>::size_type
zurueck geben...Machst Du das wirklich? Also einen std::vector<foo>::size_type als Return-Type? Wie verträgt sich das mit dem Geheimnisprinzip?
-
Hallo,
warum nicht einfach ein size_t liefern? Dieser Typ ist *garantiert* kompatibel zu vector<T>::size_type, man muss nicht soviel tippen und Marcus muss sich damit auch keine Sorgen mehr machen
-
ist size_t wirklich garantiert kompatible zu
std::vector::size_type??bei mir gibts natuerlich dann ein typedef auf vector::size_type, so dass ich für den anwender auch nur size_type returne...
aber was hat das für einen sinn wenn size_t kompatible zu vector::size_type ist? was bringt dann size_type überhaupt?
ich dachte size_type hängt vom allocator ab, was spricht dagegen einen allocator mit unsigned long long schreiben, dann wäre ein size_t mit unsigned long in bisschen zu klein...
oder erzähl ich hier gerade blödsinn?
-
ich dachte size_type hängt vom allocator ab, was spricht dagegen einen allocator mit unsigned long long schreiben
Die Allokator-Requirements. In 20.1.5 steht geschrieben:
The typedef members pointer, const_pointer, size_type and difference_type are required to be T*, T const*, size_t und ptrdiff_t, respectively
-
Nach dem Durchlesen der FAQ-Beiträge seh ich bis jetzt keinen Sinn in der Verwendung dieses neumodischen static/dynamic_cast Schnickschnacks
:
dynamic_cast bei Klassen wird doch wohl in den meißsten Fällen durch richtiges Verwenden von virtuellen Funktionen überflüssig und static_cast ist ja anscheinend das Gleiche wie der gute alte cast, nur unübersichtlicher und länger zu schreiben.
(vgl.
int i=2, j=3;
float b = float(j)/i;
mit
float b = static_cast<float>(j)/i; )Wie funktioniert dieser dynamic_cast eigentlich?
Woher weiß er, ob ein Zeiger auf eine Basisklasse tatsächlich auch einen Zeiger auf eine davon abgeleitete Klasse darstellt? (wie unterscheidet er irgendwelchen Datenmüll hinter dem Speicherbereich der Basis und tatsächliche Daten der abgeleiteten Klasse?)
-
dynamic_cast klappt nur, wenn die klassen ne virtuelle methode haben. dynamic_cast hat also netterweise zugriff auf geheime felder in der vtbl, die extra vom compiler angelegt werden, damit dynamic_cast klappt.
-
Nach dem Durchlesen der FAQ-Beiträge seh ich bis jetzt keinen Sinn in der Verwendung dieses neumodischen static/dynamic_cast Schnickschnacks :
dynamic_cast bei Klassen wird doch wohl in den meißsten Fällen durch richtiges Verwenden von virtuellen Funktionen überflüssig und static_cast ist ja anscheinend das Gleiche wie der gute alte cast, nur unübersichtlicher und länger zu schreiben.Dann lies noch mal richtig. Weder ist der static_cast das gleiche wie der C-Cast noch ist der dynamic_cast Schnickschnack. So lassen sich z.B. einige casts ausschließlich mit dem dynamic_cast realisieren.
Wie funktioniert dieser dynamic_cast eigentlich?
Das ist sein Geheimnis. Das entscheidene ist aber, dass der dynamic_cast ein *Laufzeit*-Cast ist. Er verwendet zur Laufzeit RTTI-Informationen (ähnlich wie der Exception-Mechanismus) und kann anhand dieser Informationen entscheiden ob ein Cast möglich ist oder nicht. Ist er möglich, wir der Cast durchgeführt. Ist er nicht möglich, liefert er entweder einen Nullzeiger (falls ein Zeiger gecastest wurde) oder wirft eine bad_cast-Exception (falls eine Referenz gecastet wurde).
-
Jetzt bin ich aber verwirrt.
Original erstellt von HumeSikkins:
... Demzufolge ist: return unsigned(Wert); von der Bedeutung her äquivalent zu:
return static_cast<unsigned>(Wert);Wo liegt denn nun dann der Unterschied zwischen static_cast und c-cast?
Aus den 2 FAQ-Beiträgen werd' ich nicht schlauer.PS: Und nen Beispiel für den sinnvollen Einsatz von dymanic_cast wär noch nett.
[ Dieser Beitrag wurde am 28.06.2003 um 18:28 Uhr von C14 editiert. ]
-
Wo liegt denn nun dann der Unterschied zwischen static_cast und c-cast?
In der Mächtigkeit. Der C-Cast beherrscht die Vereinigung der Möglichkeiten des static_cast, reinterpret_cast und des const_cast.
Mit dem static_cast kann man generell genau dann einen Typ s in einen Typ t konvertieren, wenn es eine *implizite* Konvertierung von t nach s gibt.
Man kann damit also z.B. ein int in eine enum casten, arithmetische Konvertierungen durchführen oder in einfachen Hierarchien einen downcast von Base* (bzw. Base&) nach Derived* (bzw. Derived&) durchführen.Und nen Beispiel für den sinnvollen Einsatz von dymanic_cast wär noch nett.
Da gibt es unzählige. Z.B. immer wenn du einen Pointer Base in einen Pointer Derived casten willst, du aber nicht sicher bist, ob der dynamische Typ tatsächlich zu Derived-kompatibel ist, kommst du um einen dynamic_cast nicht rum.
Sobald du außerdem mit mehrdeutigen Vererbungs-Hierarchien arbeitest (mehrfache/wiederholte bzw. virtuelle Vererbung), kannst du nur noch den dynamic_cast zum downcasten benutzen.
Alles in Allem verhält sich der alte C-Cast zu den neuen C++-Casts so wie Vorschlaghammer zu Feinwerkzeug.
-
Verstehe, die neuen casts sind also differenzierter.
Wahrscheinlich liegt das Benutzen von dymanic_cast aber auch häufig an nem falschen design.
Wann macht es Sinn einen Base-Pointer in einen Derived umzuwandeln? (das meinte ich mit Beispiel, sorry)
Nachher kommt noch sowas dabei heraus:if (d1=dynamic_cast<Derived1*>(pBase)) d1->f_von_d1(); if (d2=dynamic_cast<Derived2*>(pBase)) d2->f_von_d2(); ...
@volkard:
diese geheimen Felder in der vtbl machen mir etwas Angst, vor allem seitdem ich typeid(...).name() gesehen hab: Heißt das etwa, dass ich in meiner fertig-gebackenen exe bald die Klassennamen samt Abstammung wiederfinden kann?