Ne olursa olsun bir boşluk * yayınlarken static_cast veya reinterpret_cast kullanmalı mıyım


205

Static_cast ve reinterpret_cast, void * 'i başka bir işaretçi türüne dönüştürmek için iyi çalışıyor gibi görünüyor. Birini diğerine tercih etmek için iyi bir neden var mı?


78
@anon Görünüşe göre daha önce POSIX dizileriyle hiç çalışmadınız.
user470379

7
@ user470379 Vay canına ... Bu soruyu SO'ya indim! Mükemmel gözlem :-).
Ogre Psalm33

Yanıtlar:


151

Kullanımstatic_cast : Burada hangi dönüşümün yapıldığını tam olarak tanımlayan en dar dökümdür.

Kullanmanın reinterpret_castdaha iyi bir eşleşme olacağına dair bir yanlış kanı vardır, çünkü “tip güvenliği tamamen göz ardı etmek ve sadece A'dan B'ye atmak” anlamına gelir.

Ancak, bu aslında a'nın etkisini tanımlamaz reinterpret_cast. Aksine, birçoğunun reinterpret_castanlamı, “gerçekleştirdiği eşlemenin reinterpret_castuygulama tarafından tanımlandığı” anlamına gelir. [5.2.10.3]

Ancak yayın yapmak özel durumda void*için T*eşleme standart tarafından iyi tanımlanmış olduğu; yani, adresini değiştirmeden tipsiz bir işaretçiye bir tür atamak.

Bu tercih sebebidir static_cast.

Ayrıca ve tartışmasız daha da önemlisi, her kullanımının reinterpret_castdüpedüz tehlikeli olması, çünkü static_castçok daha kısıtlayıcı olmakla birlikte daha iyi bir koruma sağlaması nedeniyle herhangi bir şeyi gerçekten (işaretçiler için) dönüştürür . Bu beni yanlışlıkla bir işaretçi türünü diğerine zorlamaya çalıştığım hatalardan kurtardı.


8

Bu zor bir soru. Bir yandan, Konrad reinterpret_cast için spec tanımı hakkında mükemmel bir noktaya işaret ediyor , ancak pratikte muhtemelen aynı şeyi yapıyor. Öte yandan, işaretçi türleri arasında yayın yapıyorsanız (örneğin, bir char * aracılığıyla bellekte dizin oluştururken oldukça yaygındır), static_cast bir derleyici hatası oluşturur ve yine de reinterpret_cast'i kullanmak zorunda kalırsınız .

Uygulamada reinterpret_cast kullanıyorum çünkü döküm işleminin amacını daha açıklayıcı. Farklı bir operatörün yalnızca işaretçi yeniden yorumlamalarını (aynı adresin döndürülmesini garanti eden) belirtmesi için kesinlikle bir dava açabilirsiniz, ancak standartta bir tane yoktur.


6
" sadece işaretçi yeniden yorumlamak için farklı operatör (aynı adres döndürülen garanti) " Kucaklama? Yani operatör olduğunu reinterpret_cast !
curiousguy

2
@curiousguy Standarda göre doğru değil. reinterpret_cast aynı adresin kullanıldığını garanti ETMEZ. Sadece bir türden diğerine yeniden yorum yaparsanız ve sonra tekrar geri dönerseniz , başladığınız adresin aynısını geri alırsınız.
ClydeTheGhost

0

Her zaman mümkün olan en zayıf oyuncu kadrosunu kullanmanızı öneririm.

reinterpret_castbir işaretçiyi a float. Döküm ne kadar fazla yapı kırılırsa, o kadar fazla dikkat gerektirir.

Bu durumda, char*biraz bulana kadar c tarzı döküm kullanırım reinterpret_pointer_cast, çünkü daha zayıf ve başka hiçbir şey yeterli değil.


2
" reinterpret_cast bir göstergeyi bir kayan noktaya atamak için kullanılabilir. " Kesinlikle hayır!
curiousguy

3
Muhtemelenfloat f = *reinterpret_cast<const float*>(&p);
Ben Voigt

2
@BenVoigt Bu işaretçiler arasında döküm; bunlardan biri şamandıra göstericisi oldu.
nodakai

5
@BenVoigt "tüm ifade" bir kadro değil. İfade, oyuncu kadrosuna uygulanan bir kuralsızlıktan oluşur. İşaretçiyi yayınlamanın mümkün olduğunu iddia ettiniz float, bu yanlıştır. İfadesi alçılar void **için const float *daha sonra ve dönüştürmek için, bir KQUEUE operasyonu (dökme DEĞİL olan) kullandığı const float *için float.
MM

2
@BenVoigt bu kodu "Nasıl yayınlarım ..." diye soran birine teklif ettiniz ve daha sonra birisi kodun işaretçiler arasında yayınladığını söylediğinde (ki) "Hayır"
MM

-8

Kişisel tercihim şöyle kod okuryazarlığına dayanıyor:

void* data = something;
MyClass* foo = reinterpret_cast<MyClass*>(data);
foo->bar();

veya

typedef void* hMyClass; //typedef as a handle or reference
hMyClass = something;
const MyClass& foo = static_cast<MyClass&>(*hMyClass);
foo.bar();

Her ikisi de sonunda aynı şeyi yapıyor, ancak static_cast bir orta eşya, uygulama ortamında daha uygun görünüyorken, cast'ı yeniden yorumlamak daha düşük seviyeli bir IMHO kütüphanesinde göreceğiniz bir şeye benziyor.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.