2011-02-16 19 views
23

Merhaba ben derleyici hatası (hata Microsoft Visual Studio 2008 dan) ile bu kodu vardır:ve "kapsam çözünürlük" "adresi" C++ operatörlerin önceliği hakkında bir soru

class B 
{ 
protected: 
int b; 
}; 

class A : public B 
{ 
public: 
void foo(){ &B::b; }// error C2248: 'B::b' : cannot access protected member declared in class 'B' 
}; 

bu kod iken ücretsiz hatası: :: & göre daha yüksek bir önceliğe sahip olduğundan

class B 
{ 
protected: 
int b; 
}; 

class A : public B 
{ 
public: 
void foo(){ &(B::b); } 
}; 

iki snippet'lar

, operatörlerin öncelik benim bilgiye dayalı bana denk görünüyor (Müşterek Taarruz Uçağı" sayfa 137 de örnek tabloda 2 için bkz SİSTEM GELİŞTİRME İÇİN HAVA ARACI C++ KODLAMA STANDARTLARI A ND DEMONSTRATION PROGRAMI " http://www2.research.att.com/~bs/JSF-AV-rules.pdf)

Fakat bunlar farklı ..." Veriye işaret eden üye "ile ilgili bir şey olduğunu düşünüyorum, ancak işlevsellik önceliğine nasıl uyduğunu bilmiyorum.

Herhangi bir açıklama?

Eğer işaretçi-için-üye B::b adresini alıyorsun İlk durumda, Alessandro

+0

Önceliği yanlış olsaydı, o zaman kesinlikle (farklı) bir sözdizimi hatası olur mu? – Flexo

+2

Farkı dikkat edin: 'int * i = & (A :: b);' ancak int ::: m = &A::b; '&A::b;' –

cevap

13

teşekkür ederiz. Böyle bir işaretçi A'un üst öğesinin bir üyesi DEĞİLDİR, ancak ayrı bir nesne, korunan mekanizma üzerinden erişemez. o derleyici Şunu hangi taban sınıfı bilemez çoklu miras durumunda böylece onun temel sınıf ile niteleyerek, spesifik örneğineb ait adresi için soruyorsun çalışır İKİNCİ durumda

. Bu bağlamda korunan özellik görünür.

Not Bu derler:

class B 
{ 
protected: 
int b; 
}; 

class A : public B 
{ 
public: 
void foo(const B* b_obj) { b_obj->b; } 
}; 
+1

ayrıca '& n> B :: b; –

+0

@Gene Bushuyev Right Bu tam olarak OP'nin ikinci (çalışma) örneğiyle eşdeğerdir: Ebeveynin özel 'b' üyesinin adresini, genel bir işaretçi-üyesi değil. –

+2

Standarttan sözdizimi ve farktan söz eden herhangi bir referans? Bu sözdizimi '& (B :: b)' '' '' '' '' '' nin belirli bir örneğine ait olduğu anlamına gelir? – Nawaz

6

: Aşağıdaki (umarım daha tanıdık) kodu çalışmıyor o aynı nedenle çalışmıyor eklenen bir örnek olarak

class B 
{ 
protected: 
int b; 
}; 

class A : public B 
{ 
public: 
void foo(){ &A::b; } // Note here &A:: instead of &B:: 
}; 

Değerleri denediğinizde ve döndürdüğünüzde differece daha belirgin olur:

int*  foo() { return &(B::b);} // This is a pointer to an int 


int A::* foo() { return &B::b; } // This is a pointer to a member of type int 

As

int A::* foo() { return &A::b; } // This is a pointer to a member of type int 

bunu erişmesine izin verilen A'dan: Ne yapmak istediğiniz bir nesne aracılığı erişmek olduğunu.
B üzerinden erişerek dışardan erişerek ve böylece erişim belirticilerini tetikler.

+0

Bu, farkı daha iyi açıklıyor, bence. +1 – Nawaz

+0

"B üzerinden dışarıdan erişme gibi erişerek erişim erişim sağlayıcıları tetikler." doğru değil bence. OP'nin ikinci örneği bunu kanıtlıyor. Ayrıca, A'nın B 'gölgelemesi' B :: b' adlı başka bir özellik içerdiğini hayal edin. Daha sonra bunları ayırt etmek için '& (A :: b)' ve '& (B :: b)' yi kullanabilirsiniz. –

+0

@Tilman Vogel: Katılmıyorum. İşte bu yüzden, ikisinin ve operatör tarafından fiilen üretildiğinden nasıl farklılaştığını gösteriyorum. Referans için –

7

Bu sadece bir tamamlamadır.
§5.3.1/2 söyler:

tekli & operatör sonucu olarak işlenen bir işaretçi olup. İşlenen , bir değer veya nitelikli bir kimlik olmalıdır. ekspresyon türü ise İlk durumda, “T” sonuç türü bir kalifiye-kimliği için ...
“T. işaretçi” ise, ...üye türü bir C sınıfı T bir statik olmayan üyesi ise, sonuç türü, §5.1/7'ye göre

“tipi T. C sınıfı elemanına işaretçi ” olduğu B::b, nitelikli kimlik durumunda gelir, ancak (B::b) bunu yapmaz. Yani, derleyici bunu bir değer olarak yorumluyor.

+0

+1. Şimdi biraz daha net! – Nawaz