शुरुआत में केवल एक शून्य (आकार शून्य *) होना चाहिए (जब तक आरटीटीआई के बिना संकलित नहीं किया जाता)। यह वास्तव में नहीं होना चाहिए लेकिन यह आमतौर पर है, मैं बाद में समझाऊंगा।
vtable के लिए (कम से कम जीसीसी उत्पन्न) कपड़े की तरह दिखता है:
class_offset
type_info
first_virtual_function
second_virtual_function
etc.
type_info हो सकता है NULL
(0
) मामले में कोड RTTI बिना संकलित किया गया।
ऊपर से class_offset
बताता है कि आप वहां शून्य क्यों देखते हैं। यह वर्ग वर्ग के भीतर कक्षा ऑफसेट है। अर्थात। होने:
class A { virtual meth() {} };
class B { virtual meth() {} };
class C: public A, public B { virtual meth() {} };
मुख्य वर्ग C
में परिणाम होगा, A
वर्ग C
और B
भीतर स्थिति 0
पर प्रारंभिक स्थिति 4
(या 8
) वर्ग C
भीतर से शुरू।
पॉइंटर वहां है ताकि आप पॉइंटर को मालिक ऑब्जेक्ट में किसी भी क्लास पॉइंटर से पा सकें। तो किसी भी "मुख्य" वर्ग के लिए यह हमेशा 0
होगा लेकिन B
वर्ग वर्चुअल तालिका C
संदर्भ में मान्य है यह -4
या -8
होगा। आप वास्तव में आम तौर पर अलग से VTables उत्पन्न नहीं करता है संकलक के रूप में सी के लिए vtable (दूसरी छमाही) जांच करने की आवश्यकता:
_ZTV1C:
// VTable for C and A within C
.quad 0
.quad _ZTI1C
.quad _ZN1CD1Ev
.quad _ZN1CD0Ev
.quad _ZN1C4methEv
// VTable for B within C
.quad -8
.quad _ZTI1C
.quad _ZThn8_N1CD1Ev
.quad _ZThn8_N1CD0Ev
.quad _ZThn8_N1C4methEv
पहले compilers में ऑफसेट मालिक को वास्तविक सूचक गणना करने के लिए इस्तेमाल किया गया था विधि का आह्वान करने से पहले कक्षा। लेकिन जब इसने सीधे मालिक वर्ग पर विधि का आह्वान करते समय मामलों को धीमा कर दिया, तो आधुनिक कंपाइलर्स बल्कि स्टब उत्पन्न करते हैं जो ऑफ़सेट को सीधे घटाता है और विधि के मुख्य कार्यान्वयन पर कूदता है (जैसा कि आप विधि नाम से अनुमान लगा सकते हैं - 8
पर ध्यान दें):
_ZThn8_N1C4methEv:
subq $8, %rdi
jmp _ZN1C4methEv
स्रोत
2016-11-27 06:17:40
व्युत्पन्न कक्षा के लिए तालिका की जांच करें। मैं शर्त लगाता हूं कि सामने * शून्य * शून्य नहीं है। – wallyk
नहीं, मैंने कभी देखा है कि प्रत्येक vtable के लिए, सामने 0 है। व्युत्पन्न वर्ग या नहीं, vtable हमेशा + 8. –