2010-09-02 19 views
16

Üye türlerimi final Java'da olduğu gibi yapmak mümkün müdür? Böylece türetilmiş sınıflar bunları geçersiz kılabilir mi?Bir sınıf için 'final' üye işlevleri nasıl tanımlanır

+0

Bir röportajda sorulması gereken ilginç bir soru ... çünkü cevap hiçbir şey yapmamaktır. (Ben inanıyorum.) – Stephen

+0

Hayır C++ 'daki özel işlevler geçersiz kılmayı önler, sadece sanal ve geçersiz kılmayı bildirir. – ratty

+1

Soru çok net değil. Sanal işlevler hakkında konuştuğunuzu akılda tuttuğunuzu sormaktan rahatsız oldunuz, bu durumda cevap hayırdır: herhangi bir sınıftan herhangi bir sınıftan türetilen bir sanal işlevle elde edilen bir sınıf işlevi geçersiz kılabilir. Başkalarının işaret ettiği gibi, "sanal" olarak, tüm işlevler geçersiz kılınamaz. Java'yı bilmiyorum, bu yüzden ne zaman izin verdiğimi bilmiyorum .... –

cevap

9

Gerçekte varsayılan davranış olması çok olasıdır. Yani sınıf örnek yöntemlerinizi açıkça virtual olarak bildirmezseniz alt sınıflarda overridden olamaz (yalnızca farklı ve neredeyse her zaman hatalı olan hidden). Etkili C++ Üçüncü Baskı, Madde 36, ayrıntılı olarak bununla ilgilidir. Yani bu tam olarak değil

class B { 
public: 
    virtual void vf(); 
    void mf(); 
    virtual void mf(int); 
    ... 
}; 

class D: public B { 
public: 
    virtual void vf();    // overrides B::vf 
    void mf();      // hides B::mf; see Item33 
    ... 
}; 

D x;        // x is an object of type D 
B *pB = &x;      // get pointer to x 
D *pD = &x;      // get pointer to x 

pD->vf();       // calls D::mf, as expected 
pB->vf();       // calls D::mf, as expected 
pD->mf();       // calls D::mf, as expected 
pB->mf();       // calls B::mf - surprise! 
pD->mf(1);      // error - D::mf() hides B::mf(int)! 
pB->mf(1);      // calls B::mf(int) 

düşünün nasıl final Java davranacağını ancak sadece C++ ile bu kadar yakın alabilirsiniz. Alt sınıflamayı tamamen önlemek bir alternatif olabilir. Bunun için teknik - çalışma, ama hoş olmayan - çözüm, tüm kurucularınızı private ilan etmektir (ve elbette sınıfınızın örneğine izin vermek istiyorsanız, statik bir fabrika yöntemi sağlayın).

+0

Eğer yanlış anlaşılmasaydım, o zaman 'Overriding' bu durumda çok mümkün olan temel sınıfı 'kopyalamayı gizlemektir. İstediğim şey türetilmiş sınıfları her zaman temel sınıfın 'işlev kopyası'nı kullanması/çağırması zorlamaktır. – Hemant

+0

@Hemant, eklediğim bağlantıları ve kod örneğine bakın. –

+0

Java'yı bilmiyorum, ama ne düşündüğümden Java'da düşündüğümden, “D :: mf()” yi bile ilan edemediniz. – sbi

3

Bjarnele dan Kontrol this (İnsanların benim sınıftan türetmek durdurabilir miyim?) MSVC kullanıyorsanız

+0

A [direct] (http://www2.research.att.com/~bs/bs_faq2.html#no-derivation) linki daha kullanışlı olabilirdi: p. – Stephen

+0

@Stephen: Onu yerleştirdim. @chubsdad: Umarım sakıncası yoktur. – sbi

+0

@sbi: Oh, evet, hakları düzenle. Şimdi bunlara sahibim. Unuttum. > _ <. – Stephen

21

C++ 11 bunu desteklemek için bir final bağlamsal anahtar kelime ekler:

class B 
{ 
    public: 
    virtual void foo() final; 
}; 
class D : B 
{ 
    public: 
    virtual void foo(); // error: declaration of 'foo' overrides a 'final' function 
}; 

final GCC 4.7 ve Clang 3.0 desteklenir. Ve Sergius kendi cevabında belirttiği gibi, MSVC++, MSVC++ 2005'ten beri (sealed yazımı ile) desteklemektedir. Dolayısıyla, bir mini makronun içine yerleştirir ve derleyicinize bağlı olarak ayarlarsanız, bununla yolunuza devam edebilirsiniz. Sadece 'un en az her sıklıkta böyle bir derleyiciyi kullanarak olduğundan emin olun, böylece hataları erken algılayacaksınız.

1

Yeni C++ 11 standardı artık açıkça geçersiz kılma ve üye işlevlerinin son halini destekliyor!

İlgili konular