सभी सी ++ ऑब्जेक्ट्स, जिसमें सदस्य फ़ंक्शंस के पॉइंटर्स शामिल हैं, को वर्णों की सरणी के रूप में स्मृति में दर्शाया गया है। तो अगर आप की कोशिश कर सकते:
bool (Class::*fn_ptr)() = &Class::whatever;
const char *ptrptr = static_cast<const char*>(static_cast<const void*>(&fn_ptr));
अब (sizeof(bool (Class::*)()))
बाइट्स की एक सरणी की ओर इशारा करते के रूप में ptrptr
का इलाज, और हैश या उन बाइट्स की तुलना करें। यदि आप चाहें तो char
के बजाय आप unsigned char
का उपयोग कर सकते हैं।
यह कोई झूठी सकारात्मक गारंटी नहीं देता है - सी ++ 03 में, सदस्य कार्यों के पॉइंटर्स पीओडी हैं, जिसका मतलब है कि अन्य चीजों के बीच जिन्हें उन्हें memcpy का उपयोग करके कॉपी किया जा सकता है। इसका तात्पर्य है कि यदि समान बाइट-बाइट मान हैं, तो वे वही हैं।
समस्या यह है कि सदस्य फ़ंक्शन पॉइंटर्स के संग्रहण प्रतिनिधित्व में बिट्स शामिल हो सकते हैं जो मूल्य में भाग नहीं लेते हैं - इसलिए वे एक ही सदस्य फ़ंक्शन के लिए अलग-अलग पॉइंटर्स के लिए आवश्यक नहीं होंगे। या संकलक कुछ अस्पष्ट कारणों के लिए, उसी वर्ग के समान कार्य को इंगित करने के एक से अधिक तरीकों से हो सकता है, जो बाइट-वार बराबर नहीं हैं। किसी भी तरह से आप झूठी नकारात्मक हो सकते हैं। आपको यह देखना होगा कि सदस्य फ़ंक्शन पॉइंटर्स वास्तव में आपके कार्यान्वयन पर कैसे काम करते हैं। किसी भी तरह सदस्य फ़ंक्शन पॉइंटर्स के लिए इसे operator==
लागू करना होगा, और यदि आप यह पता लगा सकते हैं कि आप शायद ऑर्डर और हैश फ़ंक्शन कैसे निकाल सकते हैं।
यह संभावित रूप से कठिन है: सदस्य फ़ंक्शन पॉइंटर्स अजीब हैं, और स्टोरेज में किस प्रकार के फ़ंक्शन की ओर इशारा किया जाता है (आभासी, विरासत) के अनुसार अलग-अलग गैर-भाग लेने वाली "स्लैक स्पेस" शामिल होने की संभावना है। तो आपको शायद अपने कंपाइलर के कार्यान्वयन विवरण के साथ काफी महत्वपूर्ण बातचीत करनी होगी। यह आलेख आपको प्रारंभ करने में सहायता कर सकता है: http://www.codeproject.com/KB/cpp/FastDelegate.aspx
एक क्लीनर विकल्प आपके सभी फ़ंक्शन पॉइंटर्स को "कैनोनिकल" करने के लिए एक सरणी के माध्यम से एक रैखिक खोज करना पड़ सकता है, फिर तुलना करें और हैश "कैनोलिक" की स्थिति के आधार पर आपके सरणी में उस फ़ंक्शन पॉइंटर का उदाहरण। निर्भर करता है कि आपकी प्रदर्शन आवश्यकताओं क्या हैं। और यहां तक कि यदि आवश्यकताएं हैं, तो कक्षा (और इसके व्युत्पन्न वर्गों) में इतने सारे कार्य हैं कि रैखिक खोज में कितना समय लगेगा?
typedef bool (Class::*func)();
vector<func> canon;
size_t getIndexOf(func fn_ptr) {
vector<func>::iterator it = find(canon.begin(), canon.end(), fn_ptr);
if (it != canon.end()) return it - canon.begin();
canon.push_back(func);
return canon.size() - 1;
}
स्रोत
2009-08-25 14:25:58
वहाँ नहीं सामान्य रूप से एक सूचक हैश करने के लिए किसी भी कारण से, के रूप में यह बात आप उपयोग करना चाहते पर सीधे इशारा करता है।कृपया कुछ कोड प्रदान करें जो बताता है कि आप किस बारे में पूछ रहे हैं। –
आप कब कहेंगे कि एक फ़ंक्शन पॉइंटर दूसरे की तुलना में 'कम' है? –
@bojan: यदि तुलना का एकमात्र उद्देश्य उन्हें क्रमबद्ध सूची में संग्रहीत करना है, तो कोई भी निर्धारित आदेश होगा। उदाहरण के लिए बाइनरी मान। – erikkallen