"Statik sabit" ve "sabit" C ++ semantiği


149

C ++ 'da özellikle, örneğin aşağıdakiler arasındaki anlamsal farklar nelerdir:

static const int x = 0 ;

ve

const int x = 0 ;

hem staticbir bağlantı hem de bir depolama sınıfı tanımlayıcısı olarak (yani bir işlevin içinde ve dışında).


7
staticmuhtemelen C ++ 'daki en fazla aşırı yüklenmiş anahtar kelimedir. Kodunuzun anlamı, ad alanı kapsamında, sınıf kapsamında veya işlev kapsamında olmasına bağlı olarak büyük ölçüde değişir. Bunu açıklığa kavuşturmak isteyebilirsin.
sbi

1
@sbi: Zaten yaptığımı sanıyordum. İşlev kapsamı (burada bir depolama sınıfı belirticisi) ve dosya kapsamı (burada bir bağlantı belirticisi olduğu). Sınıf üyeleri ve ad alanı kapsamlı değişkenler özellikle bu soruyla ilgili olarak beni ilgilendirmiyor, ancak herhangi biri ilginç bir ayrım olduğunu hissederse, bunu da örtmekten çekinmeyin.
Clifford

@Clifford: Üzgünüm, son sözleri unuttum. Ancak, bu sizin açınızdan bir yanlış anlama ortaya koydu: In C ++, dosya kapsamı olup ad kapsamı. Herhangi bir ad alanının dışında herhangi bir şey bildirirseniz, bu yalnızca genel ad alanına ait olacaktır (ve ::önünde tanımlayıcı olmayan bir ön ek aracılığıyla erişilebilir ). Global ad alanı ile içine yerleştirilmiş herhangi bir ad alanı arasında anlamlı bir fark olduğunun farkında değilim. Kesinlikle staticnesnelerle ilgili hiçbir şey yok .
sbi

1
bağlantı görünürlükten farklıdır, onları birbirinin yerine kullanarak konuştuğunuz kişilerin ve muhtemelen kendinizin de kafasını karıştırırsınız.
Ben Voigt

1
@Ben, @sbi: Dosya kapsamının ve statik bağlantının aynı olduğunu, yalnızca statik bağlantının dosya kapsamını ifade ettiğini önermeyi düşünmedim . Bu anlamda kapsam (veya görünürlük), statik ve harici bağlantının bir niteliğidir, ikisinin de eşanlamlısı değildir. Orijinal sorunun açık ve iyi biçimlendirilmiş olduğunu ve sadece sbi'nin biraz küçümseyici sözlerine yanıt olarak yapılan yorumları tartıştığımızı hissediyorum. Burada benim anlayışımdan ziyade belirsiz İngilizce anlambilimini tartışıyoruz, bu yüzden durabiliriz diye düşünüyorum.
Clifford

Yanıtlar:


132

Dosya kapsamında, C ++ 'da fark yoktur. constdahili bağlantıyı varsayılan yapar ve tüm genel değişkenlerin statik ömürleri vardır. Ancak ilk değişken C'de aynı davranışa sahiptir, bu yüzden onu kullanmak için iyi bir neden olabilir.

Bir fonksiyon içinde, ikinci versiyon parametrelerden hesaplanabilir. C veya C ++ 'da, diğer bazı dillerin gerektirdiği gibi bir derleme zamanı sabiti olmak zorunda değildir.

Bir sınıf içinde, temelde işlevlerle aynı şey. Bir örnek constdeğeri ctor-başlatıcı-listesinde hesaplanabilir . A static const, başlangıç ​​başlatma sırasında ayarlanır ve programın geri kalanı için değişmeden kalır. (Not: staticüyeler için kod biraz farklı görünür çünkü bildirim ve başlatma ayrıdır.)

Unutmayın, C ++ ' constda salt okunur anlamına gelir , sabit değil . İşaretçiniz varsa const, programın diğer bölümleri siz bakmıyorken değeri değiştirebilir. Değişken ile tanımlanmışsa const, başlatmadan sonra hiç kimse değiştiremez, ancak başlatma yine de keyfi olarak karmaşık olabilir.


1
Dosya kapsamı diye bir şey var mı? 3.3 $ 'ı kontrol ediyordum ve bence en yakın olanı' ad alanı kapsamı '. Anladığım doğru mu? C ++ 03 standardı dosya kapsamından yalnızca Ekler
Chubsdad

2
Dosya kapsamının derleyiciden ziyade bağlayıcının bir eseri olduğunu öneririm , bu nedenle dil standardında fazla dikkat çekmeyebilir. Kesinlikle muhtemelen "derleme birimi kapsamı" dır.
Clifford

8
"Sabit, salt okunur anlamına gelir, sabit değildir", yani "Derleyici, bu sabit şeyi değiştirmeye çalışan birini görürseniz, çok yüksek sesle havlayın." Bir şeyin aynı anda sabit ve değişken olmasının nedeni budur.
Dan

5
Daha çok "Derleyici, eğer beni bu sabit şeyi değiştirmeye çalıştığımı görürseniz (veya başka birine bunu yapma izni verirseniz)", çok yüksek sesle havlayın. Çoğu bağlamda, constdeğişkenin kendisi için değil değişkenin görünümü için geçerlidir, başka biri constaynı değişkeni görmezden gelebilir ve derleyici onu değiştirdiğinde oldukça sessiz kalır.
Ben Voigt

1
@Ben: Açıkçası, C ++ 0x bu özel kullanımı kaldırmaz const, ancak constexprbunun yerine yenisi kullanılabilir (ve diğer senaryolarda da). Aslında, C ++ 0x standardı const, bu senaryoda tümleşik olmayan "değişmez türler" de kullanma yeteneğini genişletir . Sanırım constexprbu durumlar için kullanmayı tercih ederim , çünkü yine de C ++ 0x öncesi derleyicilerle geriye dönük uyumluluğu bozuyorsunuz.
Michael Burr

5

Dosya kapsamında constima staticedilen C ++ 17 standart taslağı

Bu, şu adreste bahsedilenlerin alıntıdır: https://stackoverflow.com/a/3709257/895245

C ++ 17 n4659 standart taslak 6.5 "Program ve bağlantı":

3 Ad alanı kapsamına (6.3.6) sahip bir ad, eğer adı ise dahili bağlantıya sahiptir.

  • (3.1) - açıkça statik olarak bildirilen bir değişken, işlev veya işlev şablonu; veya,
  • (3.2) - ne açıkça extern olarak bildirilmiş ne de önceden harici bağlantıya sahip olduğu bildirilmemiş, geçici olmayan sabit nitelikli türde bir satır içi olmayan değişken; veya
  • (3.3) - anonim bir sendikanın veri üyesi.

Ek C (bilgilendirici) Uyumluluk, C.1.2 Madde 6: "temel kavramlar" bunun neden C'den değiştirildiğinin gerekçesini verir:

6.5 [ayrıca 10.1.7]

Değişiklik: Açıkça const olarak bildirilen ve açıkça extern olarak bildirilmemiş bir dosya kapsamı adı iç bağlantıya sahipken, C'de harici bağlantıya sahip olacaktır.

Gerekçe: const nesneleri C ++ 'da çeviri sırasında değerler olarak kullanılabileceğinden, bu özellik programcıları her const nesnesi için açık bir başlatıcı sağlamaya teşvik eder. Bu özellik, kullanıcının birden fazla çeviri biriminde bulunan kaynak dosyalara const nesneleri koymasına olanak tanır.

Orijinal özellik üzerindeki etki: İyi tanımlanmış özelliğin anlamsallığına geçiş.

Dönüştürme zorluğu: Anlamsal dönüşüm.

Ne kadar yaygın kullanılır: Nadiren.

Ayrıca bkz: const, C ++ 'da olmadığı halde C ++' da dahili bağlantı anlamına gelir?

Başlıklar yerine yapmak isteyeceğiniz şey

Ayrıntılı olarak açıklanmıştır: 'const static' C ve C ++ 'da ne anlama geliyor?

  • pre C ++ 17: externbaşlıkta, cpp dosyasında tanım
  • post C ++ 17: başlıkta satır içi değişken

Teşekkürler, bunun C ++ 98 ile karşılaştırıldığında bile C ++ 17'de bir şans olduğunu düşünmüyorum ve soru 2010'da soruldu. Üstelik, cevabınız yalnızca bir bağlantı belirteci olarak statik ile ilgileniyor (ad alanı kapsamında) ve farklı bağlamlarda anlambilim hakkında özel olarak sorulan soru.
Clifford

@Clifford evet, kesinlikle C ++ 17'den daha eski, tüm standartları okumak için tembel ;-) Dosya kapsamı bölümünü açıklığa kavuşturacak.
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
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.