संपादित: तो मैंने देखा मैं अभी भी बाद में इस महीने पर वोट मिल रहा है, भले ही अपने मूल जवाब बुरा और गुमराह करने वाली है (मैं भी याद नहीं कर सकते कि मैं क्या समय में सोच रहा था, और यह बहुत समझ में नहीं आता है!) इसलिए मैंने सोचा कि मैं स्थिति की कोशिश करूँगा और स्पष्ट करूँगा, क्योंकि लोगों को अभी भी खोज के माध्यम से यहां जाना होगा।
सबसे सामान्य स्थिति में, आप कर सकते हैं की काफी थिंक
struct A { int i; int foo() { return i; } };
A a; a.foo();
रूप
struct A { int i; };
int A_foo(A* this) { return this->i; };
A a; A_foo(&a);
(C
तरह देखने के लिए, है ना? शुरू) तो तुम सूचक लगता होगा &A::foo
सिर्फ होगा सामान्य फ़ंक्शन पॉइंटर के समान हो। लेकिन कुछ जटिलताओं हैं: एकाधिक विरासत, और आभासी कार्यों।
तो कल्पना हमने:
struct A {int a;};
struct B {int b;};
struct C : A, B {int c;};
यह इस तरह से बाहर रखा जा सकता है:
आप, यदि आप एक A*
के साथ वस्तु ध्यान खींचना चाहते हैं कर सकते हैं या एक C*
, आप शुरुआत को इंगित करते हैं, लेकिन यदि आप B*
के साथ इसे इंगित करना चाहते हैं तो आपको कहीं बीच में इंगित करना होगा।इसलिए यदि C
B
से कुछ सदस्य फ़ंक्शन प्राप्त करता है और आप इसे इंगित करना चाहते हैं, तो C*
पर फ़ंक्शन को कॉल करें, इसे this
पॉइंटर को घुमाने के लिए जानना आवश्यक है। उस जानकारी को कहीं भी संग्रहीत करने की आवश्यकता है। तो यह फंक्शन पॉइंटर के साथ लुप्त हो जाता है।
अब हर वर्ग virtual
कार्य करता है कि के लिए, संकलक उनमें से एक सूची एक वर्चुअल टेबल कहा जाता है बनाता है। इसके बाद कक्षा में इस तालिका में एक अतिरिक्त सूचक जोड़ता है (vptr)। इसलिए इस वर्ग संरचना के लिए:
struct A
{
int a;
virtual void foo(){};
};
struct B : A
{
int b;
virtual void foo(){};
virtual void bar(){};
};
संकलक इस तरह बना अंत हो सकता है:
तो एक आभासी कार्य करने के लिए एक सदस्य समारोह सूचक वास्तव में आभासी तालिका में एक सूचकांक की जरूरत है। तो एक सदस्य फ़ंक्शन पॉइंटर को वास्तव में 1) संभवतः एक फ़ंक्शन पॉइंटर की आवश्यकता होती है, 2) संभवतः this
पॉइंटर का समायोजन, और 3) संभवतः एक vtable अनुक्रमणिका। सुसंगत होने के लिए, प्रत्येक सदस्य फ़ंक्शन पॉइंटर को इन सभी में सक्षम होने की आवश्यकता होती है। तो 16
बाइट्स के लिए सूचकांक के लिए 4
बाइट समायोजन के लिए 4
बाइट्स के लिए 8
बाइट्स है।
मुझे विश्वास है कि यह ऐसा कुछ है जो वास्तव में कंपाइलर्स के बीच बहुत भिन्न होता है, और बहुत सारे संभावित अनुकूलन हैं। शायद कोई भी वास्तव में जिस तरीके से मैंने वर्णन किया है उसे लागू नहीं करता है।
बहुत विस्तार के लिए, this देखें ("सदस्य फ़ंक्शन पॉइंटर्स के कार्यान्वयन" तक स्क्रॉल करें)।
अनिवार्य रूप से, मानक सभी डेटा संकेत, समारोह संकेत और सदस्य समारोह संकेत की आवश्यकता नहीं है एक ही आकार की है। यदि आप जानना चाहते हैं कि उनके प्लेटफ़ॉर्म पर उनका आकार क्यों नहीं है, तो आपको अपने सी ++ कंपाइलर के रखरखावकर्ता से पूछना होगा। http://www.parashift.com/c++-faq/cant-cvt-memfnptr-to-voidptr.html http://www.parashift.com/c++-faq/cant-cvt-fnptr-to-voidptr.html – Cubic
@ किरिलकिरोव कोई समस्या नहीं है। मैं हमेशा व्यंग्यात्मक नहीं हूं :) –