Yanlış form:
int &z = 12;
Doğru form:
int y;
int &r = y;
Soru :
İlk kod neden yanlış? Başlıktaki hatanın" anlamı "nedir?
Yanlış form:
int &z = 12;
Doğru form:
int y;
int &r = y;
Soru :
İlk kod neden yanlış? Başlıktaki hatanın" anlamı "nedir?
(ostringstream() << "x=" << x).str()
Yanıtlar:
C ++ 03 3.10 / 1 diyor ki: "Her ifade ya bir ldeğer ya da bir değerdir." Değerliliğe karşı değerliliğin nesnelerin değil ifadelerin bir özelliği olduğunu hatırlamak önemlidir.
Lvalues, tek bir ifadenin ötesinde kalan nesneleri adlandırır. Örneğin obj
, *ptr
, ptr[index]
ve++x
tüm Sol taraf vardır.
R değerleri, içinde yaşadıkları tam ifadenin sonunda buharlaşan geçicilerdir ("noktalı virgülle"). Örneğin 1729
, x + y
, std::string("meow")
vex++
tüm SağDeğerler bulunmaktadır.
Operatörün adresi, "işlenenin bir değer" olmasını gerektirir. bir ifadenin adresini alabilseydik, ifade bir ldeğerdir, aksi takdirde bir r değeri olur.
&obj; // valid
&12; //invalid
int & = 12;
geçersiz olduğunu basitçe cevaplamak için , standart bir dize değişmezinin bir ldeğer olduğunu, diğer değişmezlerin rdeğerler olduğunu söyler.
std::string("meow")
türde bir nesne oluşturur std::string
ve bu nesneyi belirten, 1729
yan etkisi olmayan ve değer veren bir değer verir 1729 bir tür değeri olarak int
.
"Lvalues name objects that persist beyond a single expression."
% 100 doğru bir ifadedir. Aksine, örneğiniz (const int &)1
yanlıştır çünkü "adlandırılmış" bir nesne DEĞİLDİR.
int &z = 12;
Sağ tarafta int
, integral değişmez değerinden geçici bir tür nesnesi oluşturulur 12
, ancak geçici, const olmayan bir referansa bağlanamaz. Dolayısıyla hata. Şununla aynıdır:
int &z = int(12); //still same error
Neden geçici oluşturulur? Bir referansın bellekteki bir nesneye atıfta bulunması gerektiğinden ve bir nesnenin var olması için önce yaratılması gerekir. Nesne adsız olduğu için geçici nesnedir. Adı yok. Bu açıklamadan, ikinci davanın neden iyi olduğu hemen hemen netleşti.
Geçici bir nesne const referansına bağlanabilir, yani bunu yapabilirsiniz:
const int &z = 12; //ok
Tamlık adına, C ++ 11'in geçici nesneye bağlanabilen rvalue-reference'i tanıttığını eklemek isterim. Yani C ++ 11'de şunu yazabilirsiniz:
int && z = 12; //C+11 only
Bir &&
intead olduğunu unutmayın &
. Ayrıca const
, z
bağlanan nesne değişmez- tamamlayıcıdan oluşturulmuş geçici bir nesne olsa bile, artık buna gerek olmadığını unutmayın 12
.
C ++ 11 kişiye yana rvalue referans , int&
artık bundan böyle adlandırılır lvalue referans .
12
referans verilen verilerden farklı olarak değiştirilemeyen bir derleme zamanı sabitidir int&
. Ne yapabilirsiniz do
const int& z = 12;
void f( vector<int> const & )
, değiştirilmeyecek bir vektörü iletmek için deyimsel olan bir işlevi düşünün . Şimdi sorun, bunun f( vector<int>(5) )
yanlış olması ve kullanıcının void f( vector<int> v ) { f(v); }
önemsiz olan farklı bir aşırı yükleme sağlamak zorunda kalmasıdır.
f( vector<int>(5) )
derleyici bir geçici oluşturur ve ardından referansı geçici olarak bağlar ve benzer şekilde 5
doğrudan'dan örtük bir dönüştürme varsa . Bu, derleyicinin işlev için tek bir imza oluşturmasına ve işlevin tek bir kullanıcı tarafından uygulanmasına olanak tanır. Bundan sonra, tutarlılık için sabit referansların geri kalan kullanımları için benzer davranış tanımlanır.
T const & r = *ptr;
kullanır ( r
işlevde daha sonra herhangi bir kullanım ile değiştirilebilir *ptr
ve r
çalışma zamanında var olması gerekmez) veya takma ad verdiği nesnenin adresi korunarak uygulanması gerekebilir (bir referansı bir nesnenin bir üyesi olarak saklamayı düşünün) - ki bu, otomatik başvurulan bir işaretçi olarak uygulanır.
C ++ dilinin kuralları şunlardır:
12
) oluşan bir ifade bir "rvalue"int &ri = 12;
kötü biçimlidirBunların C ++ kuralları olduğunu anlamalısınız. Onlar sadece.
Biraz farklı kurallarla farklı bir dil, örneğin C ++ 'icat etmek kolaydır. C ++ 'da, bir rvalue ile const olmayan bir referans oluşturulmasına izin verilir. Burada tutarsız veya imkansız hiçbir şey yok.
Ancak, programcının amaçladığını alamayacağı bazı riskli kodlara izin verirdi ve C ++ tasarımcıları haklı olarak bu riski önlemeye karar verirdi.
Referanslar, değişebilecek şeylere (değerlere) yönelik "gizli işaretçilerdir" (boş olmayan). Onları sabit olarak tanımlayamazsınız. "Değişken" bir şey olmalı.
DÜZENLE::
Hakkında düşünüyorum
int &x = y;
neredeyse eşdeğer
int* __px = &y;
#define x (*__px)
burada __px
yeni bir isim ve #define x
eserler sadece x
referans beyanını içeren blok içinde .
const
:)
const