2010-06-18 13 views
26

मैं वर्चुअल सदस्य फ़ंक्शन के पते को मुद्रित करने का प्रयास कर रहा हूं। तो मुझे पता है कि किस वर्ग समारोह लागू करता है मैं लिख सकते हैं:वर्चुअल सदस्य फ़ंक्शन का प्रिंट पता

print("address: %p", &A::func); 

लेकिन मैं इस तरह कुछ करना चाहता हूँ:

A *b = new B(); 

printf("address: %p", &b->func); 
printf("address: %p", &b->A::func); 

हालांकि इस संकलन नहीं है। क्या ऐसा कुछ करना संभव है, शायद रनटाइम पर vtable में पता देख रहे हो?

उत्तर

1

मुझे बहुत समझ में नहीं आता है। यदि आप एक सामान्य कार्य है:

void f(int n) { 
} 

तो आप अपने पते के ले जा सकते हैं:

f 

लेकिन आप एक समारोह कॉल, का पता नहीं ले जा सकते है जो आप करना चाहते हैं लगता है ।

+0

@GMan यही मैंने सोचा था कि मैंने कहा था। वैसे भी, मुझे नहीं लगता कि यह संभव है। –

1

मैं मानक में क्या कह सकता हूं, एकमात्र बार जब आप गतिशील बाध्यकारी प्राप्त करते हैं तो वर्चुअल फ़ंक्शन कॉल पर कॉल होता है। और एक बार जब आप फ़ंक्शन कहलाते हैं, तो आप फ़ंक्शन के भीतर बयान निष्पादित कर रहे हैं (यानी, आप कॉल में "आधा रास्ते" नहीं रोक सकते हैं और पता प्राप्त कर सकते हैं।)

मुझे लगता है कि यह असंभव है।

+0

मुझे लगता है कि यह पोर्टेबल असंभव है, लेकिन कार्यान्वयन को जानना एक वस्तु के आभासी तालिका को रनटाइम पर निरीक्षण करना संभव होना चाहिए। –

6

सदस्य कार्य करने के लिए पॉइंटर्स हमेशा सामान्य स्मृति पते नहीं होते हैं। this article में तालिका को विभिन्न कंपाइलर्स पर सदस्य फ़ंक्शन पॉइंटर्स के आकार दिखाते हुए देखें - कुछ 20 बाइट तक जाते हैं।

जैसा कि लेख में एक सदस्य फ़ंक्शन पॉइंटर वास्तव में कार्यान्वयन-परिभाषित डेटा का एक ब्लॉब है जो पॉइंटर के माध्यम से कॉल को हल करने में मदद करता है। आप उन्हें स्टोर और कॉल कर सकते हैं, लेकिन अगर आप उन्हें प्रिंट करना चाहते हैं, तो आप क्या प्रिंट करते हैं? बाइट्स के अनुक्रम के रूप में इसका इलाज करने के लिए सबसे अच्छा है और इसकी लंबाई sizeof के माध्यम से प्राप्त करें।

+4

फिर भी समस्या बनी हुई है: आप उस कार्य को कैसे पहचानते हैं जिसे 'वर्चुअल' कॉल के माध्यम से बुलाया जाता है :)? –

+1

यह सवाल का हिस्सा नहीं था? लेकिन मैं इसे 'कॉल करके' जवाब दूंगा :) – AshleysBrain

11

वर्तमान में सी ++ में ऐसा करने का कोई मानक तरीका नहीं है हालांकि जानकारी कहीं भी उपलब्ध होनी चाहिए। अन्यथा, प्रोग्राम फ़ंक्शन को कैसे कॉल कर सकता है? ...

void (A::*mfp)() = &A::func; 
printf("address: %p", (void*)(b->*mfp)); 

संभालने सदस्य समारोह प्रोटोटाइप void func() है: हालांकि, जीसीसी एक विस्तार हमें एक आभासी समारोह के पते को पुनः प्राप्त करने की अनुमति देता है कि प्रदान करता है। यह बहुत उपयोगी हो सकता है जब आप वर्चुअल फ़ंक्शन के पते को कैश करना चाहते हैं या जेनरेट कोड में इसका उपयोग करना चाहते हैं। जब तक आप -Wno-pmf-conversions निर्दिष्ट नहीं करते हैं, तब तक जीसीसी आपको इस निर्माण के बारे में चेतावनी देगा। यह असंभव है कि यह किसी अन्य कंपाइलर के साथ काम करता है।

संबंधित मुद्दे