2014-09-20 13 views
7

Statik veya dinamik olarak erişim belirticilerinin kontrol edilmesi konusunda kafam karıştı. Erişim belirticilerinin dinamik olarak denetlenmediği söylenir. Bu ne anlama geliyor ?"Erişilebilirlik statik olarak değil, C++ 'da dinamik olarak kontrol ediliyor" ifadesini anlamanız gerekir.

Bu örnek SO üzerinde farklı posts dan alınmıştır. Bu örnek

Örnek A düşünün:

class Base 
{ 
public: 
    virtual void Message() = 0; 
}; 

class Intermediate : public Base 
{ 
    //Is Message method virtual here too ? is it private or public ? 
}; 

class Final : public Intermediate { 
    void Message() { 
     cout << "Hello World!" << endl; 
    } 
}; 

Final final; 

Şimdi bu

Final* finalPtr = &final; 
finalPtr->Message(); 

yukarıdaki alışkanlık çalışması gibi bir şey ve benim anlayış Final sınıfta Mesaj Yöntemi özel olduğunu varsayalım. Bu doğru mu ? Eğer öyleyse bu neden işe yarıyor?

Intermediate* finalPtr = &final; // or Base* finalPtr = &final; 
    finalPtr->Message(); 

yöntem temel sınıf işareti türetilmiş bir sınıf ile başlatılır için yukarıdaki kodu çalışıyor nedeni budur. Eğer öyleyse neden Message() çağrısı çalışır. SO 'daki yazı, mirasın kamuya yayılmasından bu yana kamu görevi miras alınıyor? Öte yandan, sınıftaki fonksiyonun kendisi özel erişim belirticisine sahiptir (varsayılan olarak özel olarak bir sınıfta). Burada kafam karıştı ve eğer bunu açıklığa kavuşturabilirdim. Bir temel sınıf türetilmiş bir sınıf ile örneklenmişse söylemek doğru olur muydu? Ardından, temel sınıf yönteminin erişim belirteci türetilmiş sınıfın erişim belirtecine göre öncelikli midir?

Güncelleme:

Ayrıca ben fark aşağıdaki

class Intermediate : public Base 
{ 
public: //Incase this public was absent then the following example wont work 
    void Message() { 
     cout << "Hello World! Intermediate" << endl; 
    } 
}; 

class Final : public Intermediate { 
    void Message() { 
     cout << "Hello World! final" << endl; 
    } 
}; 

için Intermediate ve Final kodunu değiştirmek ve inorder Sonra böyle

Intermediate* i = new Final(); 
    i->Message(); 

olarak kullanmak durumunda "Hello World! final" çıktısını alın, arayüzü işaretlemek gereklidir kamu olarak yöntem. Neden ? Message yöntemi halka olarak devralındı. Neden şimdi halka açık olarak işaretlemem gerekiyor?

+1

Diğer mesajları bağlamış olmalısınız. Çünkü sen anlamadın, anlamadığın aynı açıklamayı alacaksın. –

+0

Link – Rajeshwar

cevap

8

sizin alıntıda deyimi (. ile * eşdeğerdir ya ->) için . operatörü uyguladık erişim denetimi ifade statik türüne göre demektir.

T bir tür için daha sonra ise:

T *t = something....; 
t->foo(); 

erişim onay adı T::foo için işaretçi aslında foo türetilmiş bir sınıfın bir nesneye işaret bile.

Bunu söylemenin başka bir yolu, erişim denetiminin derleme zamanında gerçekleştirilebilmesidir. "Çalışma zamanı erişilebilirlik hatası" diye bir şey yoktur. kodunuzu örneğinde


sahip:

Intermediate* finalPtr = something.....; 
finalPtr->Message(); 

adı

baktı Intermediate::Message niteliğinde. Intermediate sınıfı,işlevi olarak Message'a sahiptir, bu nedenle bu denetim başarılı olur.

Yorumunuz, devralınan işlevlerin erişilebilirliğinden emin olmadığınız anlamına gelir. Üç tür türev vardır (biraz kafa karıştırıcı, bunlar ayrıca private, protected, public). public kalıtım en yaygın olanıdır; Bu, temel sınıfın public üyelerinden türetilmiş sınıfın da public üyesi olduğu anlamına gelir. Base::Message yana

halka ve Intermediate sonra da açık olarak Intermediate::Message da herkese açık, Base türetilmiştir.

Net olmak gerekirse, erişim haklarına sahip adları adlarıdır. Base::Message ve Intermediate::Message iki farklı addır, ancak her ikisi de aynı işlevi adlandırır.

Final'da, private bölümünde Message adını bildirir; bu, Final::Message'un özel olduğu anlamına gelir. Miras halka açık olmasına rağmen, Final::Message adının yeni bildirimi, Base'den miras alınan bir alanı gölgelemektedir. "Güncelleştirmeyi" yanıtlamak için:

( ) Kod olduğunda:

class Intermediate : public Base 
{ 
public: //Incase this public was absent then the following example wont work 
    void Message() { 
     cout << "Hello World! Intermediate" << endl; 
    } 
}; 

Eğer toplu olarak Intermediate::Message ilan etmişlerdir. Bu nedenle, işlevi Intermediate * türünde bir işaretçi aracılığıyla çağırabilirsiniz. "Kamu" demek budur. Eğer private yaparsanız, onu arayamazsınız.

"İleti herkese açık olarak alınıyor. Neden şimdi halka açık olarak işaretlemem gerekiyor" ifadesinin ne anlama geldiğini tam olarak bilmiyorum.'u class Intermediate içine yazdığınızda, yeni bir işlev bildirir. Bu işlevin adı, devralınan adı gölgeler.

+0

Öyleyse, eğer bir temel sınıf türetilmiş bir sınıf ile örneklenmişse, söylemek doğru olur muydu? Ardından, temel sınıf yönteminin erişim belirteci türetilmiş sınıfın erişim belirtecine göre öncelikli midir? – Rajeshwar

+0

"Temel sınıf türetilmiş bir sınıfla başlatılır" diye bir şey yoktur, bu doğru olmaz. –

+0

@Rajeshwar güncellendi –

4

Bu kontrol yalnızca derleme süresinde yapılır.

Son olarak Message() öğesini finalde yaptınız, böylece finalden çağrılabilir.

Ara sınıfın, Mesajın Final sınıfında nasıl tanımlandığına dair hiçbir bilgisi yoktur.

+0

ekledi. Öyleyse bu doğru mu olacak? Bir temel sınıf türetilmiş bir sınıf ile örneklenmişse. Ardından, temel sınıf yönteminin erişim belirteci türetilmiş sınıfın erişim belirtecine göre öncelikli midir? – Rajeshwar

+0

@Rajeshwar Temel sınıfa bir işaretçiniz varsa, yalnızca temel sınıf arabirimini kullanabilirsiniz; derleyicinin, bu işaretçinin gerçekte ne gösterdiğine dair bilgisi yoktur. – molbdnilo

+0

Ne?Final (Final) 'te Message() özel yaptı, böylece Final'e bir referans/işaretçi ile çağrılamaz. Bu, derleme zamanında kontrol edilir (statik olarak), bu nedenle, çalışma zamanında (dinamik) nesnenin Son hali ise bile, işlev erişilebilir kalır. –

1

Matt McNabb'ın yanıtını kısaltmak için. Eğer işlevin erişimini belirtmezseniz, bu özeldir. Nihai :: İleti

Türetilmiş bir sınıfın, ana sınıfın erişilebilirliğini azaltmak mümkündür. Bu, bazı durumlarda yararlıdır (varsayılan/kopya yapıcıları engelleme vb. Gibi)

İlgili konular