2013-06-03 12 views
11

W tradycyjnej C można zrobić:odlewania int char użyciu C++ styl odlew

int i = 48; 
char c = (char)i; 
//Now c holds the value of 48. 
//(Of course if i > 255 then c will not hold the same value as i). 

Która z metod odlewniczych C++ (static_cast, reinterpret_cast) nadaje się do coraz to zadanie?

+0

Możesz również zrobić "char c = i;" i nie martw się o to, który rzut jest, który. Oczywiście, jeśli to zrobisz, spotkasz ludzi "rzucających wszędzie", którzy upierają się, że ostrzeżenia kompilatora zmieniają się w błędy, a następnie naprawiane tam, gdzie występują. –

Odpowiedz

8

można niejawnie konwertować pomiędzy typami liczbowymi, nawet gdy traci precyzja:

char c = i; 

Jednak może chcesz włączyć ostrzeżenia kompilatora, aby uniknąć potencjalnie stratnych konwersji jak ten. Jeśli tak, to użyj konwersji static_cast.

Spośród innych odlewów:

  • dynamic_cast działa tylko dla wskaźników lub odniesienia do polimorficznych typów klasowych;
  • const_cast nie można zmienić typów, tylko kwalifikatory const lub volatile;
  • jest dla szczególnych okoliczności, konwersja między wskaźnikami lub odniesieniami i całkowicie niepowiązanych typów. W szczególności nie wykona konwersji numerycznych.
  • Odlewy w stylu C i stylu funkcyjnego do wykonania zadania wymagającego kombinacji static_cast, const_cast i reinterpret_cast.
+2

'char c = static_cast (i);' –

17

Powinieneś użyć static_cast<char>(i), aby obsłużyć liczbę całkowitą i do char.

reinterpret_cast prawie nigdy nie powinien być używany, chyba że chcesz rzucić jeden typ w zupełnie inny typ.

Również reinterpret_cast jest zależne od komputera, więc bezpieczne korzystanie z niego wymaga pełnego zrozumienia typów oraz sposobu, w jaki kompilator implementuje rzutowanie.

Aby uzyskać więcej informacji na temat C++ odlewania Apostolskiej:

+0

Zakładając, że istnieje dobry powód, aby nie pisać po prostu "char c =" 0'' ... – Useless

+0

@Useless Znaczenie tego jest zupełnie inne niż rzutowanie z int, ustawiasz go na postać '0 "który nie jest taki sam jak numer 0. – Kevin

+3

Ale to samo, co liczba całkowita" 48 "w pytaniu, przy założeniu kodowania ASCII. Jestem uczulony na trudne wartości całkowite ASCII, gdy literały znaków są w każdym razie bardziej czytelne. – Useless

-2

Korzystanie obsady statycznego prawdopodobnie spowodować coś takiego:

// This does not prevent a possible type overflow 
const char char_max = -1; 

int i = 48; 
char c = (i & char_max); 

Aby zapobiec ewentualnemu typu przepełnienie można to zrobić:

const char char_max = (char)(((unsigned char) char(-1))/2); 

int i = 128; 
char c = (i & char_max); // Would always result in positive signed values. 

Gdzie reinterpret_cast prawdopodobnie tylko bezpośrednio przekształcić do char , bez żadnego zabezpieczenia odlanego. -> Nigdy nie używaj reinterpret_cast, jeśli możesz również użyć static_cast. Jeśli przesyłasz między klasami, static_cast zapewnia również, że oba typy są zgodne (obiekt jest pochodną typu rzutowania).

Jeśli twój obiekt jest polimorficzny i nie wiesz, który to jest, powinieneś użyć dynamic_cast, który wykona test typu w czasie wykonywania i zwróci nullptr, jeśli typy nie są zgodne.

JEŚLI potrzebujesz const_cast, najprawdopodobniej zrobiłeś coś nie tak i powinieneś pomyśleć o możliwych alternatywach, aby naprawić poprawność stałej w swoim kodzie.

0

reinterpret_cast nie może być użyty do tej konwersji, kod nie zostanie skompilowany. Według C++ 03 standardowej sekcji 5.2.10-1:

Conversions that can be performed explicitly using reinterpret_cast are listed below. No other conversion can be performed explicitly using reinterpret_cast.

konwersja ta nie jest wymieniona w tej sekcji. Nawet ta jest nieprawidłowy:

long l = reinterpret_cast<long>(i) 

static_cast jest ten, który ma zostać użyty tutaj. Zobacz pytania: this i this SO.