Nasıl bir const doğruluk dönüştün? [kapalı]


25

15 yıllık C ++ 'dan sonra hala const kullanmayı sevmeyi öğrenmedim. Kullandığını anlıyorum, ama aslında hiçbir zaman doğru bir şekilde doğru davranmanın karşılaştığım sorundan kaçındığı bir durumda olmadım.

Peki nasıl olur da yardımların yararına ulaştın?


3
Const doğruluğunun, eğer bir constrcut veya bir sizeof operatörü gibi bir sorunu çözmek için bir araçtan daha doğru olduğunu düşünüyorum.
legends2k

9
"Const'un C ++ 'da çalışmasının nedeni, onu serbest bırakabilmenizdir. Bunu ortadan kaldıramazsanız, dünyanız berbat olur." - Anders Hejlsberg
Mason Wheeler

1
const ayrıca bir C tipi değiştiricidir ve ilk ANSI C standardından beri olmuştur.
Huperniketes

Java / C # tarafından şımartıldığından, aldığım her fırsatı değerlendirmeyi bırakmayı seven paranoyak bir türüm. Bir şey ters gidecekse mutlaka ters gider. Bir derleme zamanı veya çalışma zamanı yardımı varsa, o zaman beni say! 3-4 kez duyduğum anda bir dönüşüm oldum ve bu bağlantının bir kısmını takip ettim (sözdizimini görmeye yetecek kadar, nedenini okumak zorunda değildim): possible.com/Cpp/const.html Sırf yüzümdeki bir şey henüz patlamamış ... ... doğru dürüst olmak için çok az çaba harcar ve acıtmaz. Joel'in düşüncelerine göz atın: joelonsoftware.com/articles/Wrong.html
İş

Yanıtlar:


28

Ben felsefeyi kucaklamaya çalışana kadar ikna olmadım.

İlk önce consten temel sınıf üyelerimin salt okunur üyelerine ve üye işlev tartışmalarına koyarak başladım .

Oradan artık derleyemedim. Daha sonra, bu temel sınıfları kullanarak koda girme konusunda ısrar ettim, önceki consteklerin onlardan yaptığım kullanımla karşılaştırıldığında gerçekten meşru olup olmadığına bakın . Kodun diğer kısımlarına da tutarlılık eklediğim için bazı hataları düzeltmeme yardımcı oldu.

Bu bulaşıcı. Kodun çoğu daha da fazla kabardı ve hata ayıklamak daha kolay oldu çünkü yapmamanız gereken bir şeyi değiştirmeye başlarsanız derleyicinin sizi durduracağından emin olmanızı sağlıyor.

Uygulamayı tekrar çalıştırdıktan sonra, kod okurken çok daha az hata ve anlaşılması daha kolay olan daha hızlı (daha önce farkettiğim algoritmaları değiştirmek zorunda kalmadım) değiştirmek zorunda kaldım.

İkna oldum.

Şimdi, bence ek bir çok iddia kullandığınızda daha da iyi olduğunu düşünüyorum, çünkü yeni kod yazmanız veya mevcut kodu değiştirmeniz gerektiğinde kendinizi güvende hissetmenizi sağlar. Derleyicinin gerekirse seni durduracağını biliyorsun. Değiştirmemeniz gereken her şeyi kontrol etmek zorunda olduğunuzu unutabilmenizi sağlar ve daha sonra işletmeye özgü düşünme veya mimari düşünme için daha fazla düşünme zamanınız olur.


8
Bulaşıcı için +1, temelde bir const dönüşmesi olmalı ya da tamamen önlenebileceği anlamına gelir.
Martin Wickman

Ayrıca, doğruluk yapmayan kütüphanelere güvenmemeniz de gerekir. Yaklaşımınız, herhangi bir gui işlevini çağıramayacağınız anlamına gelmediği için işe yaramaz, çünkü bunlar const değildir - veya her gui çağrısında onu kullanmanız gerekir.
Martin Beckett

4
"Hata ayıklamayı daha kolay buldum" için +1 const, değiştirmek zorunda kalmayacağımı bildiğim yerel değişken için bile kullanıyorum , bu şekilde kod okurken bir ifveya a forveya whatelse üzerinden kaybedebilirim: değişkenim sabit, ben değişmeyeceğini biliyorum ! İyileştirmeler hakkında daha az umursayamazdım, ama sınırlı bir beynim var ve az sayıda girintiye + inşaat doğruluğuna çok yardımcı oldum!
Matthieu M.

@MatthieuM .: Hiç Haskell'e geçiş yapmayı düşündün mü? ;-)
Giorgio,

@ Giorgio: Ben araştırdım, hatta "Gerçek Dünya Haskell" satın almak kadar ileri gitti. Dürüst olmak gerekirse, varsayılan olarak tembellikten ve fırlayan birçok şifreli operatörden heyecan duymuyorum.
Matthieu M.

15

Hiçbir zaman nesne yönelimli programlama savunucusu olmadım ve daha az büyüdüğüm bir şey olursa, genel olarak programlama hakkında daha fazla şey öğrendim. Farklı programlama paradigmaları üzerinde çalıştığım için, değişmezliğin program tasarımının temel kavramlarından biri olduğunu ve herhangi bir felsefeye göre yazılmış yazılımı etkilediğini anladım . Fonksiyonel programlamada optimizasyon ve eşzamanlılık gibi basit güvenlik garantilerinin üstüne çıkması çok önemlidir.

Temel olarak, değişken durum için iyi bir nedeniniz olmadıkça, değiştirilemez olan her şey muhtemelen olmalıdır . Tecrübelerime göre, bu amaç doğrultusunda herhangi bir dilde programlar yazmak daha güvenli ve daha iyi kodlara yol açmaktadır . Uygun olan constyerlerde kaybedecek hiçbir şeyiniz yok - değişmezlik ücretsiz!

(Bu arada, her türlü constaçıkça nitelendirilmediği sürece , C ++ lehçesi için bir GCC çatalı oluşturma fikri ile oynamıştım mutable. Bu tür bir şeye destek varsa, onu korumayı ve kullanmayı tamamen taahhüt edeceğim.)


Bir OO açısından, değişmezlik sınırsız yazma erişimini önleyerek enkapsülasyonu zorlar. Sınıflar arasındaki eşleşmeyi azaltır, çünkü değişmez nesneler kendi durumlarını tamamen yönetmeli ve dolayısıyla sıradan değerler gibi davranmalıdır. Const doğruluğu, özellikle eşzamanlı programlama bağlamında program doğruluğunu kanıtlama sürecini önemli ölçüde kolaylaştırır. C ++ referansı ve C ++ 0x değer referans referansı anlamıyla, değiştirilemeyen nesneleri, her yere kopyalamanın ek yükü hakkında endişelenmeden yararlanabilirsiniz. Ayrıca, çoğunlukla değişmez nesnelerle çalışıyorsanız, derleyici oldukça şaşırtıcı bir optimizasyon sihri oluşturabilir.

Her constyere yazmanın berbat olduğunu biliyorum , ancak buna hızla alışıyorsunuz ve faydalar güvenilirlik ve bakım açısından zamanla ortaya çıkıyor. Parlak bir yazar değilim ve bunun için bir dava açmak için kanıtlanmış zor bir görev gibi görünüyor, ancak programların düzenlenmesi ve uygulanmasında bence doğrulığın geliştirici olarak benim için son derece yararlı olduğunu biliyorum. Bu konuda en iyi öğretmen.


2
Temel olarak az önce const doğruluğunun iyi bir şey olduğunu söyledin. Bunun "daha güvenli, daha iyi kodlara yol açtığını" söylediniz. Nedenini söyleyebilir misin
David Reis

Ben tamamen değişmezlik kampındayım, en sevdiğim dil Erlang. Ancak C ++ 'da const yoluyla değişmezliğin gerçekten ücretsiz olmadığını savunuyorum. Aynı yöntemin daha az okunabilen kod, const ve const olmayan versiyonları, veya cast const gibi olumsuz yönleri "sadece başka bir seçenek yoktu".
grok

1
mutableConst doğruluğu açısından açık bir anlamı olduğu için sadece kullanılmasını tavsiye etmem. Bu, bu veri nesnesinin, nesne davranışını etkilemeyen şekillerde değişebileceği ve yanıtları önbelleğe almak gibi şeylere izin verdiği anlamına gelir. Başka bir anahtar kelime oluştur.
David Thornley

2
@David Thornley: Tutarlılık uğruna, mutablemantıklı bir seçimdir. Yerel bir değişken için void alter(mutable Point&)olduğu gibi bu mantıklı mutable int fooolanı ve bu dillerin hiçbiri var olan dille veya mevcut kullanımla çakışmaz mutable. Ayrıca, Object mutable* mutablegerekli ya da doğru olup olmadığına dair bir uyarı olacak kadar korkutucu görünüyor.
Jon Purdy

Çatalı hiç yaparsanız, bunun yerine CLang ile düşünün - daha az acı verici olmalı.
gf

6

Const doğruluğunun avantajı, programa bir disiplin kazandırması ve programın bölümleri hakkında gerekçelendirmeyi kolaylaştırmasıdır.

Disiplin, bir şeyin nerede değişebileceğini bilmeniz gerektiğidir. Karşılık gelen avantaj, durumu değiştiren şeyleri söyleyebildiğinizde bir kod parçasının ne yaptığını görmenin daha kolay olmasıdır.


1
"İnsanların okuması için programlar yazılmalı ve sadece makinelerin çalışması için bu arada yazılmalıdır." - Abelson & Sussman, SICP
Brandon DuRette

4

Olmak const ben dökme operatörleri kullanmıyor benzer bir sorun yakın tedavi tasarımın doğruluğu doğru vurgular; bu yüzden alçı kullanmama ve doğru olmama, en az değişken kullanım - tüm bunlar tasarımın ne kadar iyi olduğunu ölçmek için işaretçilerdir, ancak eldeki genel sorunu çözmek için gerçek araçlar değildir.

Not: Bir constkere onu kullanmanın doğruluğunu anladığımda tamamen ikna oldum ;)



2

Const-doğru kod yazmak için iki ana neden görüyorum. Birincisi, derleyici arkadaşınız ve const kullanarak sizi potansiyel hatalar konusunda uyarmasına izin veriyorsunuz. İkincisi, inşaat doğruluğunun kodu daha okunaklı hale getirmesidir. Örneğin, hangi fonksiyon argümanlarının giriş olduğunu ve hangilerinin çıkış olduğunu her zaman bilirsiniz. Ayrıca hangi üye işlevlerin nesneyi değiştirdiğini ve hangilerinin yapmadığını da biliyorsunuz. Bu şeyleri anında kodu okumak zorunda kalmadan biliyorsunuz. Bu, elbette, çok akıllıca bir kullanım olduğunu varsayar const_cast.


2

Bunun mümkün olduğunu bildiğim anda bir dönüşüm oldu. Bana 'iyi bir programlama stili' bakış açısından mantıklı geldi. Const’in doğru olmasının iyi bir uygulama olmasının çeşitli nedenleri vardır:

  • Okunabilirlik ve anlama. Başkasının kodunu okuyorsam ve bir işlev parametre olarak const referansını alırsa, parametrenin yalnızca salt okunur bir değişken olarak kullanılması gerektiğini biliyorum. Bu, özellikle kodun çok iş parçacıklı bir ortam olması durumunda büyük bir kazançtır.
  • Derleyici, optimizasyon geçişlerine yardımcı olmak için const niteleyicisini kullanabilir.
  • Diyelim ki değişmesini istemediğim bir durumda A sınıfı bir nesnem var. O zaman bu nesne için çağrılabilecek tek üye işlevi const olanlardır.

2

Diğer cevaplarda ele alınan iki noktayı özetlemek ve yeni bir tane eklemek için:

  • constkodu API'nizin kullanıcılarına belgeler. Bir işlev ile arayan arasında, işlevin parametrelerini değiştirmeyeceği bir sözleşme oluşturur. ( const_castBir işlevin parametresini değiştirmesine izin vermediğini, bu parametrenin parametrelerini değiştirmeyen ancak constek açıklamaları unutturan diğer işlevlere geçirilmesine izin verdiğini lütfen unutmayın .) İşlev / döngü / etc içerisinde de kullanışlıdır. değişmeyen bir döngü gibi.

  • constniyetinizi derleyiciye belgeler. Derleme zamanında hataları bulmak, her zaman bu kod parçasının çalışmasını beklemekten iyidir.

  • constgüvenli polimorfizm türü için gereklidir. İşaretçiler (tüm biçimlerde, yalnızca ham işaretçiler değil), yalnızca varsa kovaryant olurlar const(Not: "const to pointer" ile aynı değildir). Kovaryans salt okunur bir arayüz gerektirir ve zıtlık salt okunur bir arayüz gerektirir.

Bunlardan ikincisi önce öğrendim. Daha constönce hata yakalamanın yararlarını görmeye ve bunu yerel halkta vb. Kullanmaya başlamaya başlayana kadar sadece işaretçi ve referans parametrelerinin hedefiyle başladım.

Daha sonra çoğu #definetürün (C ++ 'da) tür sabitliğinin ek faydalarıyla global sabitler tarafından değiştirilebileceğini öğrendim . Ben de orada kullandım.

Sonunda, tip sistemleri ve lambda matematiği üzerine bir ders aldım, constve olmayan consttiplerin temelde farklı olduğunu (farklı işlemleri desteklediklerinden dolayı) öğrendim ve o zamandan beri C ++ kodunu çok fazla kullanmadan yazmayı bile düşünmedim const.


1

İşte başkalarının bahsetmediğini gördüğüm 5 kuruş. Değişkenleri dolaşırken, fazladan yapıları ve yıkımları ve kopyaları önlemek için gerçekten gerekmedikçe, değere göre geçmek istemezsiniz. Bu nedenle, gerçekten değere göre geçmek zorunda olmadığınız sürece, her yerde referansları kullanmak, geçen değeri değiştirmek istemeseniz bile, önemli bir performans artışıdır. Bu nedenle, tüm argümanlarının referanslarını alan fonksiyonlara sahip olduğunuzda, arayan kişiye fonksiyonun neyi değiştirmeyeceğini bildirmeniz gerekir.

Aynı ilke, ancak const kullanmanın pratik bir nedenini eklemek istedim.

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.