2013-01-11 12 views
6

Odnosząc się do SO C++ FAQ When should static_cast, dynamic_cast and reinterpret_cast be used?.const_cast vs reinterpret_cast

const_cast służy do usuwania lub dodawania const do zmiennej i jest jedynym niezawodnym, zdefiniowanym i legalnym sposobem usunięcia stałej. reinterpret_cast służy do zmiany interpretacji typu.

Rozumiem w sposób rozsądny, dlaczego zmienna const powinna być rzucana do nie const tylko przy użyciu const_cast, ale nie mogę znaleźć uzasadnionego uzasadnienia problemów przy użyciu reinterpret_cast zamiast const_cast, aby dodać constness.

Rozumiem, że używanie reinterpret_cast do równomiernego dodawania nie jest normalne, ale czy byłoby to UB, czy potencjalna bomba czasowa do używania reinterpret_cast do dodania constness?

Powodem Byłem zmieszany tutaj jest ze względu na rachunku

Głównie, jedyną gwarancją można uzyskać z reinterpret_cast jest to, że jeśli rzucisz wynik z powrotem do oryginalnego typu, dostaniesz dokładnie ta sama wartość.

Więc jeśli dodam constness korzystając reinterpret_cast a jeśli reinterpret_cast wynik z powrotem do oryginalnego typu, powinno skutkować powrotem do oryginalnego typu i nie powinny być UB, ale który narusza fakt, że należy używać tylko const_cast aby wyjąć constness

na oddzielnej nocie standardowe gwarancje, które można dodać constness użyciu reinterpretacji case

5.2.10 reinterpretacji obsady (7) ...... Kiedy prvalue typu v "Wskaźnik do T1" jest konwertowany na typ "wskaźnik do cv T2", wynikiem jest static_cast (static_cast (V)), jeżeli oba T1 i T2 są typu standardowego układu (3.9) oraz wymagania centrowania T2 nie są bardziej restrykcyjne niż T1 ........

+0

@clossvoters: Czy możesz odesłać mnie do duplikatu odpowiedzi na to pytanie? – Abhijit

+1

'const_cast' obejmuje także dodanie/usunięcie' volatile'. –

+0

@MikeDeSimone: Tak, zdecydowanie, ale mój obecny fokus to tylko constness – Abhijit

Odpowiedz

9

reinterpret_cast zmienia interpretację danych w obiekcie. const_cast dodaje lub usuwa kwalifikator const. Reprezentacja danych i stała są ortogonalne. Dlatego warto mieć różne słowa kluczowe do przesyłania.

Więc jeśli dodam constness korzystając reinterpret_cast a jeśli reinterpret_cast wynik z powrotem do oryginalnego typu, powinno skutkować powrotem do oryginalnego typu i nie powinny być UB, ale który narusza fakt, że należy używać tylko const_cast usunąć constness

To nie byłoby nawet skompilować:

int * n = new int; 
const * const_added = reinterpret_cast<const int *>(n); 
int * original_type = reinterpret_cast<int*>(const_added); 
    // error: reinterpret_cast from type ‘const int*’ to type ‘int*’ casts away qualifiers 
+1

Patrz "5.2.10 Reinterpret cast" : 'Gdy wartość v znaku typu" wskaźnik do T1 " jest konwertowana na typ" wskaźnik na cv T2 ", wynikiem jest static_cast (static_cast (v)), jeśli oba T1 i T2 są standardem typy -layout (3.9) i wymagania T2 dla linii trasowania nie są bardziej restrykcyjne niż wymagania T1. Wygląda na to, że możesz dodać constness używając reinterpret cast. – Abhijit

+1

Obiekty nie będące stałymi mogą zawsze być niejawnie konwertowane na const, bez potrzeby jakiejkolwiek obsady.Nie widzę powodu, dla którego 'reinterpret_cast' powinno stanowić wyjątek od tej reguły. – StackedCrooked

3

należy nie tylko być dodanie const z reinterpret_cast. A reinterpret_cast powinno być przede wszystkim to: reinterpretowanie wskaźnika (lub cokolwiek innego).

Innymi słowy, jeśli przechodzisz z const char* do char* (mam nadzieję, że istnieje zły interfejs API, którego nie możesz zmienić), to Twoim przyjacielem jest const_cast. Tak naprawdę to wszystko ma być.

Ale jeśli trzeba iść z MyPODType* do const char*, trzeba reinterpret_cast, a to po prostu miły, nie wymagając const_cast na wierzchu.

0

Jedyne miejsce, gdzie mogę myśleć o odnosząca reinterpret_cast z const-ności jest przy przejściu const obiekt do API, które akceptuje wskaźnik void -

UINT ThreadFunction(void* param) 
{ 
    const MyClass* ptr = reinterpret_cast<const MyClass*>(param); 
} 
1

Jest jedna rzecz, aby pamiętać: Nie można użyć wartości const_cast, aby można było zapisywać zmienną o wartości const. Możesz go użyć tylko do pobrania odniesienia nie-const z odwołania do const, jeśli odwołanie do const odnosi się do obiektu niestałego. Brzmi skomplikowanie? Przykład:

// valid: 
int x; 
int const& x1 = x; 
const_cast<int&>(x1) = 0; 
// invalid: 
int const y = 42; 
int const& y1 = y; 
const_cast<int&>(y1) = 0; 

W rzeczywistości oba te elementy będą się kompilować, a czasami nawet "działać". Jednak drugi powoduje niezdefiniowane zachowanie iw wielu przypadkach kończy działanie programu, gdy stały obiekt jest umieszczony w pamięci tylko do odczytu.

To powiedziawszy, jeszcze kilka rzeczy: reinterpret_cast to najpotężniejsza obsada, ale także najbardziej niebezpieczna, więc nie używaj jej, chyba że musisz. Jeśli potrzebujesz przejść z void* do sometype*, użyj static_cast. Kierując się w przeciwnym kierunku, użyj wbudowanej niejawnej konwersji lub użyj jawnego static_cast. Podobnie z dodawaniem lub usuwaniem const, które jest również dodawane niejawnie. Odnośnie reinterpret_cast, zobacz także dyskusję pod adresem C++ When should we prefer to use a two chained static_cast over reinterpret_cast, gdzie omówiono alternatywę, która jest mniej hackowska.

Uli

0

tak, jak pan wie, const_cast oznacza, że ​​usuwa constness z określonego typu.

Ale kiedy potrzebujemy dodać constness do typu. Czy jest jakiś powód, dla którego musimy to zrobić?

np

void PrintAnything(void* pData) 
{ 
    const CObject* pObject = reinterpret_cast<CObject*>(pData); 
    // below is bla-bla-bla. 
} 

reinterpret_cast nie ma nic wspólnego z 'const'.

const_cast oznacza dwie rzeczy. Pierwszym z nich jest usunięcie constness z typu, a drugim jest nadanie jego kodu wyraźności. Ponieważ możesz używać przesyłania za pomocą rzutowania w stylu C, ale nie jest to wyraźne, więc nie jest zalecane.

Nie działają one same. jest zdecydowanie inny.

Powiązane problemy