Yanıtlar:
İlk olarak, bu çizgilerin eşdeğer olmadığını anlayın .
int* anInt = (int*)aFloat; // is equivalent to
int* anInt = reinterpret_cast<int*>(aFloat);
Burada olan şey, programcının derleyiciden döküm yapmak için elinden geleni yapmasını istemesidir.
Fark önemlidir çünkü static_cast sadece dönüştürmek için "güvenli" bir taban türü isteyecektir, burada reinterpret_cast herhangi bir şeye dönüşecektir, muhtemelen sadece istenen nesnenin hafızası üzerinde istenen hafıza düzenini eşleyerek.
Dolayısıyla, "filtre" aynı olmadığından, belirli bir döküm kullanmak C dökümünü kullanmaktan daha açık ve güvenlidir, derleyiciye (veya dynamic_cast kullanıyorsanız çalışma zamanı impl.) Güvenirseniz, nerede yanlış bir şey yaptığınızı size söyler , avong C döküm ve reinterepret_cast ile.
Artık bu daha açık, başka bir şey daha var: static_cast, reinterpret_cast, const_cast ve dynamic_cast'in aranması daha kolay .
Ve nihai nokta: çirkinler . Bu aranıyor. Potansiyel olarak buggy kodu, kod kokuları, hatalara neden olabilecek bariz "hileler", çirkin görünümle ilişkilendirildiğinde izlenmesi daha kolaydır. Kötü kod çirkin olmalı .
Bu "tasarım gereği". Ve bu, geliştiricinin işleri daha iyi yapabileceğini (gerçekten gerekli değilse, atmalardan tamamen kaçınarak) ve nerede iyi olduğunu bilmesine izin verir, ancak nerede olduğunu çirkin olarak işaretleyerek kodda "belgelenir".
Yeni stil dökümünü tanıtmanın ikincil bir nedeni, C stili dökümlerin bir programda fark edilmesinin çok zor olmasıydı. Örneğin, sıradan bir editör veya kelime işlemci kullanarak yayınları kolayca arayamazsınız. C tipi dökümlerin bu görünmezliği özellikle talihsizdir çünkü potansiyel olarak zararlıdırlar. Çirkin bir operasyonun çirkin bir sözdizimsel formu olmalıdır. Bu gözlem, yeni tarz dökümler için sözdizimini seçme nedeninin bir parçasıydı. Başka bir neden, yeni stil dökümlerin şablon gösterimi ile eşleşmesiydi, böylece programcılar kendi dökümlerini, özellikle çalışma zamanı kontrol edilen dökümlerini yazabilirler.
Belki, static_cast yazması çok çirkin ve göreceli olarak zor olduğundan, birini kullanmadan önce iki kez düşünmeniz daha olasıdır? Bu iyi olurdu, çünkü dökümler gerçekten modern C ++ 'da çoğunlukla önlenebilir.
C ++ yayınları daha kısıtlayıcıdır (bu nedenle niyetinizi daha iyi ifade edin ve kod incelemesini kolaylaştırın vb.). İhtiyacınız olursa aramak da çok daha kolay.
Seçenek C: bir "C ++ tarzı" döküm, çünkü bir yapıdan ayırt edilemez:
int anInt = int(aFloat);
ya da:
int anInt(aFloat);
Bunun yanı sıra, iyi anlaşılmış ilkelleri olan bu önemsiz durumlar dışında, C stili dökümler üzerinde x_cast <> kullanmayı tercih ediyorum. Bunun üç nedeni vardır:
Programcının gerçekleştirmeye çalıştığı işlemi daha dar bir şekilde tanımlarlar.
C stili dökümlerin yapamayacağı eylemleri gerçekleştirebilirler (özellikle, birden fazla miras zincirinin dalları arasında çapraz geçiş yapabilen dynamic_cast <> durumunda).
Onlar çirkin . Programcının tip sistemine karşı çalıştığını yüksek sesle ilan ederler. Bu durumda, iyi bir şey.
C dilinde kod yazıyorsanız bir C döküm kullanın. C ++ ile yazıyorsanız, bir C ++ cast kullanın.
Çoğu döküm uygun tip güvenliği bozarken, C ++ olanlar daha kısıtlayıcıdır ve bu nedenle C dökümüyle olduğundan daha az tip güvensizsiniz.
Ben aşırı yük zorlamak rağmen (T *) NULL kullanarak birini tolere edebilir ...
C / C ++ - tarzı döküm hakkında birkaç kural var:
const_cast
. Açık nedenlerden dolayı. Ne yazık ki, klavyenin uzanmasına ve programcının parmağını kırmasına neden olan bir sabitin kaldırılmasına ilişkin kuralım onaylanmadı.reinterpret_cast
. Gerçekten C'nin sahip olmadığı türden bir döküm: bu tamsayı'nın bitlerinin aslında bir şamandıra biti gibi davran. Bu gibi tatsızlığı önler (int)(*(int*)(&floatVar))
.dynamic_cast
" Kelimelerini yazarsanız , polimorfik sınıf hiyerarşinizi ve tasarımınızı durdurun ve yeniden değerlendirin. Bu kelimeleri silene kadar sınıf hiyerarşinizin tasarımını yeniden değerlendirmeye devam edin.static_cast
.# 4'ün ardındaki mantık basitçe bunun önemli olmamasıdır. Diğer kurallara uymayan koşullar ya açık ya da gerçekten düşük düzeydedir. İnt-to-float gibi basit türlerin iyi anlaşılmış bir dönüşümü için özel sözdizimi gerekmez. Ve eğer bir şeyin derin, çirkin bağırsaklarına düştüyseniz, bir şeyin derin, çirkin bağırsaklarına düştünüz. Dişler, pençeler ve ateşin hemen hemen onu vermiş olması nedeniyle "burada ejderhalar" olduğuna dikkat çekmeye gerek yoktur.
dynamic_cast
son derece geçerli bir araçtır. Nadiren yararlı, itiraf edeceğim, ancak küresel değişkenler gibi şeylerin Şeytanından uzak. Bununla birlikte, öncelikle, sizi caydırdım çünkü C tarzı dökümlerin kullanımı ya da kullanılmamasıyla ilgili soruya cevap vermediniz .
Yukarıdaki mesajlara göre C ++ (statik) döküm pratikte biraz daha güvenlidir.
Farklı döküm türleri ve profesyonelleri ve eksileri hakkında daha fazla bilgi aramak akıllıca olabilir.
Neden daha çok arka plana sahip olmak için. .
http://en.wikipedia.org/wiki/Static_cast
Gerçekten hangi dilde çalıştığımıza bağlı, çünkü ne dediklerini biliyorsunuz: Roma'da Roman konuşuyor. Bu yüzden C programlıyorsam, C özelliklerini max için kullanmaya çalışıyorum, ancak C ++ programlıyorsam devam edin ve bazı insanlar bu yaklaşımı sevmese bile max C ++ özelliklerini kullanıyorum çünkü onlar kod "daha az taşınabilir" yapar, umurumda değil, ben C ++ ve programlama C ++, ve kod derlemek için tamamen C ++ uyumlu bir derleyici gerekir, aksi takdirde farklı bir şey ile çalışacağını söylüyorlar ilk başta.
static_cast, vb. şablonlarda kullanıldığında C stili dökümlerle ilgili sorunlar nedeniyle icat edildi. Bir şablon yazıyorsanız veya kodunuz daha sonra bir şablona dönüştürülebilirse, C ++ stili dökümler kullanmak iyi bir fikirdir. Bunun nedeni, C ++ stili ifadelerin daha iyi ifade etme amacı taşımasıdır, bu nedenle C stili dökümlerin yanlış bir şey yapacağı durumlarda beklenen sonuçları verecektir (şablon parametreleri olarak belirli türler verilir).
Bunun dışında, onlara ihtiyacı olan belirli bir sorun varsa C ++ tarzı dökümleri kullan diyorum - dynamic_cast en yaygın olanıdır, ancak bu muhtemelen her gün bir şey değildir.
Başka bir şey ve C tarzı bir döküm biraz daha az dağınıklık ve okunabilirliğe yardımcı olabilir veya belki de okuyucunun bu döküm stiline ne kadar aşina olduğuna bağlı olmayabilir. Benim görüşüme göre çok önemli değil, çoğunlukla kişisel bir tercih şey, ancak bazı insanlar C stilini sevmiyorsa şaşırmayın.
Son not - eğer bu çok önemli bir şey söz konusu ise, büyük olasılıkla yanlış bir şey yapıyorsunuzdur. Bazı durumlarda bunun istisnaları vardır, ancak çoğu üst düzey kodun çok sayıda (varsa) dökümüne ihtiyacı olmamalıdır.
reinterpret_cast<int>(double);
. C-tarzı bir döküm ile bir int'e bir çifte döküm yapmak tamamen mümkündür, ancak reinterpret_cast ile yapmak mümkün değildir. Timbo'nun bunu size işaret ettiğini görüyorum ve düzeltebileceğinizi söylediniz, ancak dört yıl sonra yanlış kalıyor. Yine de düzeltilmiş olsaydı, sizi aldatırım, çünkü bir döküm kullanmanız için mükemmel geçerli nedenler vardır. İşte daha iyi bir cevap: stackoverflow.com/a/332086/3878168