2016-04-10 114 views
2

Çok sayıda gönderi okudum ve herkesin söylediğine göre, sanal tablo nesne başına değil, nesne ve nesnenin yalnızca paylaşılan vtable için _vtpr işaretçisi var. Ama bu örneği düşünün lütfen:Polimorfizmde sanal tablo

class Base 
{ 
public: 
    virtual void func1(void) {} 
    virtual void func2(void) {} 
private: 
    int dummy; 
}; 

class Der1 : public Base 
{ 
public: 
    virtual void func1(void) {} 
private: 
    int dummy; 
}; 

class Der2 : public Base 
{ 
public: 
    virtual void func2(void) {} 
private: 
    int dummy; 
}; 

int main(void) 
{ 
    Base * obj1 = new Der1; 
    Base * obj2 = new Der2; 
} 

obj1 ve obj2 o bir benzersiz Taban sınıf vtable ile ilgilidir mu? Cevabın hayır olduğuna inanıyorum ama açıklayabilir misiniz? Ve eğer bu nesnelerin her ikisi de aynı vtable ile ilişkiliyse, hangi yöntemlerin çağrılması gerektiği nasıl belirlenir? Örneğin, obj1-> func1 başvurusu obj2-> func1'den farklıdır.

GÜNCELLEME: Base * obj1 = new Der1; yaparken
ne gibi faaliyetleri yürütür? Birisi bu eylemler için bir sözde kod yazabilir mi?

+2

. Derleyici uygulayıcılarının istediklerini yapmakta özgür oldukları anlamına gelir. Herhangi bir vtable olacağının bir garantisi bile yok. Bu, neden bir C++ ABI'mizin bulunmamasının en önemli nedenlerinden biridir. Bunu "diyor" diyen herkese söyle. – Drop

+0

Muhtemelen 'Der1' ve' Der2' her birinin kendi vtable var, değil mi? –

+1

Bu [cevap] (http://stackoverflow.com/a/562240/2352671) tarafından [Johannes Schaub - litb] (http://stackoverflow.com/users/34509/johannes-schaub-litb) – 101010

cevap

1

Umarım aşağıdaki örnek size yardımcı olacaktır. Türetilmiş sınıflar yalnızca temel sınıfın sanal tablosunu kopyalar, ancak uygun girişi değiştirebilirler. Kırmızı kısım, verilen sınıfın v-tabloda girişi değiştirdiğini gösterir. Bu nedenle, türetilmiş sınıf örneği oluşturulduğunda, değiştirilen tablo (bu sınıfa özgü) dikkate alınır.

Derleyicinin taban sınıfının ne kadarının işlendiğine bağlıdır (temel sınıf çok sayıda işlev içeriyorsa - tüm sanal işlev tablonun kopyasına sahipse ve girişleri değiştirir mi?). IMO, derleyici işleri basitleştirmek için her türetilmiş sınıf için tüm tabloyu kopyalayacaktır. Aramak için uygun yöntemin aranması basitleşir. C++ standardında vtable tanımı tanımlanmadı enter image description here

+0

Yeni veterinerler nerede ve ne zaman bulunacak? Yanılıyorsam düzeltin: Derlemede Der1 ve Der2 vtables RW veri bölümüne oluşturulacak; Base * obj1 = new Der1 atanırken; ve obj1-> func1() tarafından çağrıldığında, Der1 vtable, söz konusu yöntemin girişini bulmak için kaldırılır. Ve Base * obj1 ve obj2 sadece işaretçiler olduğundan, bunlar vtable'a sahip değildir ve kopyalanamaz. –

+0

Bu konudaki anlayışımı onaylayabilir misiniz yoksa yanılıyor muyum? –

+0

Veri bölümlerini ve derleyici/linker'ın v-tablolarını tam olarak nasıl eklediğini bilmiyorum. Kavramsal olarak v-tablolarını global bağlantılı listeler olarak düşünebilirsiniz. Belirli bir sınıf v-masanın kafasından birini tutar (ve dolayısıyla sınıfın büyüklüğü 'sizeof (pointer)' ile eklenir). Türetilmiş bir sınıf başka bir v-tablo bağlantılı liste oluşturur ve sınıf (örnek değil) bu bağlantılı listeyi işaret eder. Türetilmiş sınıf bir sanal işlevi yeniden tanımlamazsa, mevcut v-tablosuyla bağlantılı listeye işaret eder. Bir sanal sınıf hiyerarşisi, bu tür bağlantılı liste başlıklarına birden çok işaret edebilir ve dolayısıyla boyut artar. Lütfen kitap okuyun/onlin – Ajay