Zarówno static_cast, jak i reinterpret_cast, wydają się działać dobrze, aby rzutować void * na inny typ wskaźnika. Czy istnieje dobry powód, by faworyzować jedną nad drugą?Powinieneś użyć static_cast lub reinterpret_cast podczas rzutowania pustki * na cokolwiek
Odpowiedz
Użyj static_cast
: jest to najwęższa obsada, która dokładnie opisuje, co tutaj się dokonuje.
Istnieje błędne przekonanie, że użycie reinterpret_cast
byłoby lepszym rozwiązaniem, ponieważ oznacza "całkowite zignorowanie bezpieczeństwa typu i po prostu rzutowanie od A do B".
To jednak nie opisuje efektu reinterpret_cast
. Raczej reinterpret_cast
ma wiele znaczeń, dla wszystkich, które głosi, że „mapowanie wykonywane przez reinterpret_cast
jest realizacja zdefiniowane.” [5.2.10.3]
Jednak w szczególnym przypadku odlewania z void*
do T*
odwzorowanie jest całkowicie dobrze zdefiniowany przez standard; mianowicie, aby przypisać typ wskaźnikowi beztekstowemu bez zmiany jego adresu.
Jest to powód, aby preferować static_cast
. Dodatkowo, i prawdopodobnie ważniejsze, jest to, że każde użycie reinterpret_cast
jest wręcz niebezpieczne, ponieważ konwertuje wszystko na cokolwiek innego (na wskaźniki), podczas gdy static_cast
jest znacznie bardziej restrykcyjne, co zapewnia lepszy poziom ochrony. To już uratowało mnie od błędów, w których przypadkowo próbowałem przymusić jeden typ wskaźnika do drugiego.
To jest trudne pytanie. Z jednej strony, Konrad znakomicie wskazuje na definicję specyfikacji dla reinterpret_cast, chociaż w praktyce prawdopodobnie robi to samo. Z drugiej strony, jeśli rzutujesz między typami wskaźników (co jest dość powszechne, gdy na przykład indeksujesz w pamięci za pomocą znaku *), static_cast wygeneruje błąd kompilatora i będziesz zmuszony użyć reinterpret_cast tak czy inaczej.
W praktyce używam reinterpret_cast, ponieważ jest bardziej opisowy w stosunku do operacji rzutowania. Z pewnością można stworzyć argumenty dla innego operatora, który wskaże tylko reinterpretację wskaźnika (co gwarantuje zwrócenie tego samego adresu), ale nie ma go w standardzie.
"różny operator, który wskaże tylko samą reinterpretację wskaźnika (co gwarantuje zwrócenie tego samego adresu) _" Przytulić? Ten operator ** to ** 'reinterpret_cast'! – curiousguy
Moje osobiste preferencje jest na podstawie kodu umiejętności jak ta:
void* data = something;
MyClass* foo = reinterpret_cast<MyClass*>(data);
foo->bar();
lub
typedef void* hMyClass; //typedef as a handle or reference
hMyClass = something;
const MyClass& foo = static_cast<MyClass&>(*hMyClass);
foo.bar();
Obaj zrobić to samo w końcu, ale static_cast wydaje się bardziej odpowiednie w środkowym-Ware, Środowisko aplikacji, a ponowne zinterpretowanie oddania wydaje się bardziej podobne do tego, co zobaczysz w bibliotece IMHO na niższym poziomie.
Drugi przykładowy kod nie zostanie skompilowany. –
Proponuję zawsze używać najsłabszej możliwej obsady.
reinterpret_cast służy do rzutowania wskaźnika na float. Im bardziej struktura jest przełamująca, tym więcej uwagi wymaga jego użycie.
W przypadku char *, używałbym rzutowania w stylu c, dopóki nie mamy reinterpret_pointer_cast, ponieważ jest słabszy i nic więcej nie jest wystarczające.
"_reinterpret_cast może być użyty do rzucania wskaźnika na float." "Z pewnością nie! – curiousguy
z pewnością tak, curiousguy. Sprawdź ponownie standard. –
Czy możesz podać przykład? – curiousguy
- 1. Czy static_cast <T> (...) podczas kompilacji lub uruchamiania?
- 2. reinterpret_cast
- 3. static_cast bezpieczeństwo
- 4. const_cast vs reinterpret_cast
- 5. W jaki sposób static_cast może rzutować int na char, ale nie reinterpret_cast?
- 6. Na Pustki typ zwracany
- 7. static_cast wskaźnika elementu w kontekście constexpr na g ++
- 8. SFINAE: 'static_cast <void>()' lub ', void()'?
- 9. odlewania poprzez pustkę * zamiast korzystania reinterpret_cast
- 10. Jak użyć wyraźnego rzutowania, aby ukryć to ostrzeżenie?
- 11. Zwrot pustki?
- 12. W jaki sposób można użyć static_cast w przypadku dziedziczenia wirtualnego?
- 13. Przeciążanie static_cast?
- 14. OutOfMemoryError: Przestrzeń sterty Java podczas rzutowania liczbowego prymitywu na char.
- 15. Zwiększenie rzutowania shared_ptr do void *
- 16. niejawna konwersja vs. static_cast gdy upcasting
- 17. reinterpret_cast rzuca dala kwalifikatorów
- 18. Czy static_cast jest niewłaściwie używany?
- 19. Cel c UIPageViewController usuwa cień podczas rzutowania
- 20. reinterpret_cast dziwność (oddzielone przecinkiem wyrażenie)
- 21. reinterpret_cast, char * i niezdefiniowane zachowanie
- 22. Typ asercji rzutowania na betonowej strukturze?
- 23. Czysty sposób rzutowania na rzeczywisty typ obiektu
- 24. Co powinieneś nazwać kontrolerem w MVC? Kiedy powinieneś utworzyć nowy?
- 25. Dlaczego Java ArrayList używa rzutowania na element zamiast rzutowania na tablicę?
- 26. C++ std :: copy z typem rzutowania na klasę pochodną możliwą?
- 27. Jeśli przesłonię window.onerror w javascript powinieneś zwrócić true lub false?
- 28. EZPDF - dokumentacja, samouczek, cokolwiek?
- 29. Czy MySQL może zrównoleglić podzapytania UNION (lub cokolwiek w ogóle)?
- 30. PHP (lub cokolwiek innego) Konfiguracja CGI w web.config IIS
Lepsze pytanie brzmiałoby: "Jak uniknąć używania wskaźników pustych w moim kodzie?". Nie jest to trudne - nie pamiętam, kiedy ostatnio go używałem. –
@on Wygląda na to, że nigdy wcześniej nie pracowałeś z wątkami POSIX. – user470379
@ user470379 Wow ... właśnie dlatego wylądowałem na to pytanie w SO! Doskonała obserwacja :-). –