2014-04-14 38 views
26

http://herbsutter.com/2008/01/01/gotw-88-a-candidate-for-the-most-important-const/'da "en önemli const" ifadesiyle C++ tarafından, geçici bir nesneyi yığında bulunan bir referansa geçici bir nesneyi bağlamanın, referansın yaşam süresi boyunca geçici ömrün ömrünü uzattığını kasten belirtir. Ben C++ sadece neden olduğu zaman değil, değil, ancak, const olduğunda nesnenin ömrünün uzatılmasına izin veriyor merak mı? Özelliğin ardındaki mantıklı nedir ve neden bu kadar zor olmalı? Bu izin verildi eğerNeden "en önemli const" const olmalı?

int& x = 5; 
x = 6; 

ne yapılsın:

+1

Buradaki Standart'dan bir alıntı yapmayı umuyoruz, çünkü kendimi hiçbir zaman 'const' gerektirmediğine inandım. (N3936'da 12.2 p4 ve 5'e bakın). – BoBTFish

+0

Böylece, derleyici, nesnenin kapsam dışına çıkmasından önce geçici olarak hiçbir yolun değiştirilmediğini doğrulamak zorunda kalmaz. –

+4

@BoBTFish: Referanslara bağlı olan geçici ömürlerin ömrüne bakıyorsunuz. Onları ilk etapta nasıl bağlayacağınıza dair kurallar için [dcl.init.ref] 'e bakınız (C++ 11'de 8.5.3). Özellikle, p5'in son mermi: "referans, uçucu olmayan bir ** const ** tipi [veya] bir referans referansına verilen bir değer referansı olmalıdır." –

cevap

14

aşağıdaki düşünün? Buna karşılık, eğer

const int& x = 5; 

x değiştirmek için hiçbir yasal yolu var olacağını yaptı. geçicileri const olmayan lvalue başvuruları bağlamak olsaydı

void square(int &x) 
{ 
    x = x * x; 
} 

int main() 
{ 
    float f = 3.0f; 

    square(f); 

    std::cout << f << '\n'; 
} 

, yukarıda mutlu derlemek, daha ziyade şaşırtıcı sonuçlar üretecektir (3 yerine 9 bir çıkış):

+0

Değeri 5 olan gizli bir yerel değişken oluşturulmalıdır. İzin vermemek için teknik bir neden yoktur. –

+1

@NeilKirk Ancak, int & 'den beklediğiniz bir şey değil, sadece derleyici tasarımcıları için bir yük olacak ve int x = 5'den farklı olmayacaktı. –

+2

@tohecz ancak bu, const ref bağlanmasının normal işlevlerden gelen dönüş değerleri ile nasıl uygulandığıdır. Tüm özellikler derleyici tasarımcıları için “yük” ler, bu bir özellik olmaması için bir sebep değil! – dan

24

İşte bir örnek.

+0

İlginç, Bunu düşünmemiştim. –

+2

Neden 3 çıktı? – 0x499602D2

+0

Bu her zamanki açıklamadır, bence. Kopya stilinde başlatmaya izin verilirse, ancak parametrelendirme başlatılmamışsa ne olur? Zaten açık ve örtük dönüşümler var. –

1

Yapı referanslarının, normalde bir adresi bile olmayan nesnelere bağlı olabileceğini unutmayın. Bir const int & işlev parametresi, 42 değişmez sabit ifadesi tarafından oluşturulan bir bağımsız değişken alabilir. 42 adresini alamıyoruz, bu yüzden onu const int * alan bir işleve iletemeyiz.

const başvuruları, bu gibi rezonanslara bağlanabilmeleri için özel olarak "kutsanmış" dır.

Tabii ki, 2 + 2 gibi geleneksel rvalues ​​için, ömür boyu bir sorun değil. Sınıf tipi renginleri için bir sorun. ilgili referans sahası boyunca aklı başında kalacak şekilde

referans bağlanmasını 42 farklı olarak, yaygın bir kullanım sahip değildir, bir nesne bırakılır, bu kullanım süresi sahip, uzatılabilir.

Bu const'ın ömür boyu bir uzantıya neden olması değil, const olmayan bir referansa izin verilmemesidir. Bu izin verildi, aynı zamanda ömür boyu bir uzantısı gerektirir; kapsamının bazı kısımlarında kötü giden bazı referanslara izin verilmesinin hiçbir anlamı yoktur. Bu davranış, bir referansın bir işaretçiden daha güvenli olduğu kavramını zayıflatır.

İlgili konular