2017-09-08 39 views
29

const vector<int *>'un gerçek anlamından emin değilim, bu yüzden bir fikir edinmek için aşağıdaki kodu derledim ama şimdi daha kafam karıştı. Burada durmuş olsaydıNeden int göstergelerinin const vektöründe dengesiz öğe ötelenebilir?

vector<int *> v; 
int x = 1, y = 2; 
v.push_back(&x); 
v.push_back(&y); 

const vector<int *> w = v; 
w[0] = &y; //failed. Element is a constant pointer? 
*(w[0]) ++; //failed. Element pointer references to constant value? 

, ben const vector<int *>const int * const bir vektör olduğu varsayılmıştır olurdu, ama o zaman açıkça bu varsayımı çelişki aşağıdaki çalıştı.

*(w[0]) += 3; //passed. Value not constant? 
*(w[0]) = 20; //passed. Why... 

Şimdi *(w[0]) bana bilinmeyen bir nedenle belli ki farklı ++ ve += ve atama davranır. Kendimi const vector'un vector sınıfının sabit bir nesnesini ilan ettiğine ve yukarıdaki sonuçların vector sınıfının aşırı yüklenmesinin gerçek uygulamasına bağlı olabileceğine inandım. Ama kafamı bunun etrafına saramam. Birisi açıklayabilir mi lütfen?

İlgili ise, Mac'te g ++ 4.2 kullandım.

+1

Bunu ilginç bulabilirsiniz: Önceden arttırma yapmak için gönderiyi değiştirin ve ikinci hata örneğinde ne olduğunu görün. '++ * (a [0]); '. – WhozCraig

+1

Sanırım büyük bir karışıklık kaynağı yazıyor '* (w [0]) ++;' yerine (* w [0]) ++; '(ki bunun muhtemelen beklenen sonuç olduğunu düşünüyorum). Operatör önceliği bazen biraz zor olabilir. – Kat

cevap

33

Neden int göstergelerinin const şablonunda dengesiz öğe ötelenebilir?

const vector<int *> için bir unsur değildir işaretçi kendisi işaretleyici tarafından işaret nesnesini yaratabilir veya değiştirebilir, böylece const olmayan için const işaretçi, yani int * const olabilir, ancak.

Operator Precedence göre, sonek artışı operatör operator* daha yüksek önceliğe sahiptir, bu yüzden *(w[0]) ++;

işaretçiyi artış ilk olarak gerçekleştirilir
* ((w[0]) ++); 

eşdeğerdir, o zaman başarısız olur. w[0] = &y; da işaretçiyi değiştirmeye çalışıyor, bu yüzden de başarısız oluyor.

Diğer taraftan, (*w[0]) ++; (yani pointee üzerinde artış) iyi olurdu. Ve aşağıdaki ifadeler de iyi, çünkü ikisi de işaretçiler değil işaretçinin işaret ettiği nesneleri değiştiriyorlar.

*(w[0]) += 3; //passed. 
*(w[0]) = 20; //passed. 
9

operator precedence meselesi.

*(w[0]) ++'u yaptığınızda, işaretçisini işaretçisini değiştirmeye çalışırsınız.

*(w[0]) += 3'u yaptığınızda, işaretçiyi işaret ettiği verileri değiştirirsiniz.

5

w bir const vector<int *> olduğunu. Vektöre constniteleyici uygulanır. Bu nedenle, karşılık gelen const elemanı işlevi operator[] için kullanılacaktır:

const_reference operator[](size_type pos) const;

vektör ulaşım kolaylığı const ve tip int * (olup const int *) elemanlarını içerdiği ifade w[0] tipi int * const& olan (const int *& yerine).constness işaretçi kendisi, veri işaret edilen uygulanır: Bu, sabit bir int bir int olup bir işaretçi referans sabit bir işaretçi referans vardır. Eğer (const olan) vektör döndürür işaretçi değerini değiştirerek değil *(w[0]) += 3 yaparak

ancak bu işaretçi işaret ediyor değer. Bu işaretçi, int * const türünde (ve const int * değil) olduğundan, işaret ettiği şeyi değiştirebilir, bu nedenle çalışır. Ancak, w[0] = &y yapmak sabit bir işaretçi üzerinde bir atama gerçekleştirir, bu nedenle derleme yapmaz.

0

const vector<T> Eğer T const & (yaniconst T &) olarak elemanlarına erişim sağlar. Bu durumda, T, int * şeklindedir, bu nedenle buişaret eden bir işaretçi için bir const başvuru int * const & olur. İşaretçi sabit, ancak int değil.

vektör tipi (yanivector<const int*>) bu durumda, elemanlar int const * const & üzerinden erişilebilir olur vector<int const *> olmak için gerekli olacaktı.

Alt satırda, constness, şablonlarla değil, işaretçilerle geçişlidir. Ve eğer şablonlara işaretçiler koyarsanız, her iki davranıştan da bir şeyler alırsınız.

İlgili konular