2017-08-04 7 views
3

ich gelernt, dass in C++,Function-Casts vs. Konstruktor

typedef foo* mytype; 

(mytype) a  // C-style cast 

und

mytype(a)   // function-style cast 

das gleiche tun.

Aber ich bemerke, dass die Funktion-Stil-Besetzung die gleiche Syntax wie ein Konstruktor teilen. Gibt es nicht zweideutige Fälle, in denen wir nicht wissen, ob es sich um eine Besetzung oder einen Konstruktor handelt?

char s [] = "Hello"; 
std::string s2 = std::string(s);  // here it's a constructor but why wouldn't it be ... 
std::string s3 = (std::string) s; // ... interpreted as a function-style cast? 
+2

Eigentlich in dem Beispiel zeigen Sie * beide * cases einen 'std :: string' Konstruktor aufrufen. Der * selbe * Konstruktor sogar. –

+0

Hinweis: In C++ sollten Sie generell die expliziten Umwandlungen 'static_cast',' reininterpret_cast', 'const_cast',' dynamic_cast', 'static_pointer_cast',' reininterpret_pointer_cast', 'const_pointer_cast' und' dynamic_pointer_cast' (und 'move' & 'Forward' - ja, sie * sind nur Cast *) über C-Style-Casts. Sie sind einfacher in Code zu suchen, expliziter in Bezug auf Intention und sicherer (schlimmster Cast von C-Style-Cast ist das Erzeugen von 'reininterpret_cast', gefolgt von' const_cast' zum Beispiel). –

Antwort

10

Syntaktisch ist es immer ein Cast. Diese Umwandlung ruft möglicherweise einen Konstruktor auf:

char s [] = "Hello"; 
// Function-style cast; internally calls std::basic_string<char>::basic_string(char const*, Allocator) 
std::string s2 = std::string(s); 
// C-style cast; internally calls std::basic_string<char>::basic_string(char const*, Allocator) 
std::string s3 = (std::string) s; 
0

Der Compiler weiß. Und es ruft den Konstruktor auf, wenn es in beiden Fällen einen gibt.

1

Konvertierung ist eine Form der Initialisierung. Wenn ein Typ implizit in einen anderen konvertierbar ist, ist eine funktionale Umwandlung eine Form der direkten Initialisierung. Der Compiler weiß, welche Typen konvertierbar sind.

Wenn etwas in einen Klassentyp konvertiert wird, wird entweder ein Konvertierungskonstruktor des Zieltyps oder ein Konvertierungsoperator des Quelltyps verwendet. In Ihren Beispielen rufen beide Umwandlungen den Standardkonstruktor auf.

+0

Danke. Ok, der Compiler weiß, aber wie kann ich wissen, welche Fälle über Konstruktor konvertierbar sind oder einfach nur den Typ ändern, ohne den Wert zu ändern (wie ein C-Style-Cast)? – Basj

+0

@Basj 'wie kann ich wissen, welche Fälle konvertierbar sind" können Sie den Compiler fragen mit 'std :: is_convertible' oder Sie können die Definition der Klasse (und die Definition der Klasse des Quellobjekts, falls zutreffend) lesen, um zu sehen, ob Die Klasse verfügt über einen geeigneten Konvertierungskonstruktor (oder das Quellobjekt verfügt über den entsprechenden Konvertierungsoperator). Die Konvertierung in einen Klassentyp ist immer ein Aufruf an einen Konstruktor. Sie können herausfinden, ob ein Typ eine Klasse ist, indem Sie seine Definition betrachten. – user2079303

+0

"Immer wenn etwas in einen Klassentyp konvertiert wird, wird ein Konstruktor aufgerufen." - nicht wahr. Ein Konvertierungsoperator könnte stattdessen aufgerufen werden. Und das ruft nicht notwendigerweise auch einen Konstruktor auf (normalerweise würde es aber ein zwischengespeichertes Objekt als Referenz zurückgeben). –

Verwandte Themen