2011-02-16 24 views
7

Bir özet dersine bir başvuru olduğunda ne anlama gelir? Kodda buldum ve bunu anlayamıyorum.Soyut sınıf için referans

Soyut bir sınıfın başlatılamayacağını düşündüm. Nasıl referans verebilirsin?

+2

Bu soru çok belirsiz. Bir kod örneği yayınlayın ve neden karıştırdığınızı açıklayın. – aschepler

+0

Diğer ucunda somut alt sınıfların olabileceği anlamına mı geliyor? Liskov ikame prensibine bağlamak için – Piskvor

cevap

13

Soyut bir sınıfa yapılan bir başvuru, soyut bir sınıfa yönelik bir işaretçi gibidir: soyut sınıfın soyut olmayan alt sınıfının bir nesnesine başvurması gerekir. Java'da bir arabirime işaretçiye benzer bir şekilde, . sözdizimini kullanarak başvurulan sınıfta sanal yöntemleri çağırmak için böyle bir başvuru kullanabilirsiniz.

6

Özet bir sınıf, türetilmek üzere tasarlanmıştır. Liskov ikame ilkesi kabaca, soyut bir tabandan türetilen türlerin soyut parçalarını kullanan her şeyin, taban polimorfik olarak kullanılarak eşit derecede iyi çalışmasının gerekli olduğunu belirtir. Bu, tabana bir referans veya işaretçi kullanılması gerektiği anlamına gelir.

+3

+1. Bu tür değerli ipuçları, bitişik kabinlerde daha yetkin meslektaşları ile sonuçlanan yazılım tasarımı/programlamasının daha derin alanlarını araştırmak için yeni başlayanlara rehberlik ediyor :) –

+0

@Als: Liskov'un anlaşılmasının uzun vadesini gerçekleştirmek için +1.;-) –

3
class Abstract 
{ 
public: 
    virtual void foo() = 0; 
}; 

class Implementation : public Abstract 
{ 
public: 
    void foo() { std::cout << "Foo!" << std::endl; } 
}; 

void call_foo(Abstract& obj) { obj.foo(); } 

int main() 
{ 
    Abstract *bar = new Implementation(); 

    call_foo(*bar); 

    delete bar; 
} 

bar soyut bir sınıfa pointer olup. * işlecini kullanarak dereferanslı olabilir ve call_foo içine reference olarak geçirilebilir, çünkü call_foo soruyor (Abstract* bir işaretçi isterken, Abstract& bir başvuru istiyor). Yukarıda

, özet sınıfa referans geçirilir ve foo() (yerine işaretçi -> notasyon) . gösterimi kullanılarak çağrıldığında Implementation ne olduğu için, bu, Foo! basar.

Bu yardımcı olur umarım.

+0

Tabii ki burada bir işaretçi oluşturmanız bile gerekmiyor. 'u değiştirebilirsin Özet * bar = new Implementation(); ile Özet & bar = Uygulama(); veya hatta Uygulama çubuğu; – DanDan

+0

Bu durumda, evet, ancak sadece işaretçiler ve referanslar arasındaki farklılıkları/benzerlikleri görüntülüyordum. :) – James

+0

Tamam, iyi örnek o zaman :) – DanDan

2

C++'daki başvurular gizli işaretçiler gibi (neredeyse) davranır. Özellikle, bir işaretçi ile alabileceğiniz aynı polimorfik davranış, bir referans ile bunu başarabilirsiniz. Bu bir önceki hatlarında bir yerde tanımlanan bir tamsayıdır olduğunu varsayarak

int *i = &a; 
int &j = a; 

eşdeğerdir (hemen hemen) Aşağıdaki vardır. Referans j'nin meydana gelmesinin ardından, (* i) 'nin oluşumlarına mükemmel şekilde eşdeğerdir. En önemli fark, bir referansın size bir bellek yönetimi hatası vermemesidir, bir işaretçi ise (yeni (ler) i ve silme (ler) i idare etmek sizin sorumluluğunuzdur). Ayrıca, bir işaretçi bir şeye işaret etmek zorunda değildir, bir şeye atıfta bulunmuyorsa bir referans olamaz. Bunun dışında, aynı şekilde davranmaları için onları düşünebilirsiniz. Bu nedenle, soyut bir nesneye başvurmak kesinlikle yasaldır. Genellikle polimorfik davranışın referanslar veya işaretçilerle elde edilebildiği fonksiyon imzalarında bulabilirsiniz. Aşağıdaki kod parçası bir operator() aşırı yükler sınıfı varsayılarak

A a; 
A* ptr = &a; 
A& ref = a; 
ref(); 
ptr->operator()(); 
(*ptr)(); 

göstermektedir gibi Ancak referanslar, daha hafif bir sözdizimi verir.

İlgili konular