2011-01-28 20 views
21

मैं एक सदस्य समारोह हस्ताक्षर के लिए प्रकार परिभाषा घोषित करने के लिए चाहते हैं। वैश्विक समारोह typedefs इस तरह दिखेगा:सी ++ typedef सदस्य समारोह हस्ताक्षर वाक्य रचना

typedef int (function_signature)(int, int); 
typedef int (*function_pointer) (int, int); 

लेकिन मैं एक सदस्य समारोह के लिए एक ही बात करने में सक्षम नहीं कर रहा हूँ:

typedef int (foo::memberf_signature)(int, int); // memberf_pointer is not a member of foo 
typedef int (foo::*memberf_pointer)(int, int); 

यह मेरे लिए तार्किक लगता है, क्योंकि "foo ::" पहली कक्षा foo में एक सदस्य का उपयोग करने के लिए वाक्यविन्यास। मैं केवल हस्ताक्षर टाइप कैसे कर सकता हूं?

+0

क्यों, क्या आप ऐसा करने की कोशिश कर रहे हैं? –

+4

मैं उलझन में हूं, क्या आखिरी 'टाइपपीफ' नहीं है जो आप चाहते हैं? – GManNickG

+0

यह मेरे लिए असंगत लगता है। ग्लोबल-स्कोप पर घोषित एक फ़ंक्शन टाइप करना संभव है, लेकिन एक विधि टाइप करना संभव नहीं है। और हाँ, मैं हस्ताक्षर और फ़ंक्शन पॉइंटर प्रकार के बीच अंतर कर रहा हूं। – 0xbadf00d

उत्तर

10

अजीब समारोह सूचक वाक्य रचना के बारे में प्रश्नों के लिए, मैं व्यक्तिगत रूप से एक धोखा शीट का उपयोग करें: The Function Pointers Tutorial (downloadable here, यह उनका कहना है के लिए Vector करने के लिए धन्यवाद)।

एक सदस्य समारोह के हस्ताक्षर है, तथापि, एक नियमित रूप से समारोह के हस्ताक्षर से थोड़ी अलग, जैसा कि आप का अनुभव है।

आप शायद जानते हैं, एक सदस्य समारोह एक छिपा पैरामीटर, this, जिसका प्रकार निर्दिष्ट करने की आवश्यकता है।

typedef int (Foo::*Member)(int, int); 

आपके द्वारा निर्दिष्ट है कि पहला तत्व समारोह के लिए पारित हो जाएगा एक Foo* (और इस प्रकार अपने विधि वास्तव में 3 तर्क, लेता है, जब आप इसे के बारे में सोच सिर्फ 2.

लेकिन वहाँ है नहीं करते है भी एक और कारण, प्रकार निर्दिष्ट करने के लिए मजबूर कर रहा है।

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

इसलिए, वर्ग को संदर्भित करता है वर्ग हस्ताक्षर का हिस्सा है, और वहां कोई काम नहीं है।

+0

आपका लिंक टूटा हुआ है –

+0

@ BЈовић: और यह भी एक अच्छा लिंक था ... ओह शुक्र है कि मैं एक दूसरा लेख जानता था;) –

+0

[** फंक्शन पॉइंटर्स ट्यूटोरियल **] के लिए _downloads_ के साथ नया कामकाजी लिंक (http: //www.newty.de/fpt/dload.html) – Vector

1

कारण यह आपके वर्तमान वाक्यविन्यास के साथ काम नहीं करता है यह है कि ऑपरेटर प्राथमिकता यह बताती है कि आप किसी भी प्रकार के प्रकार के foo::memberf_signature नामक फ़ंक्शन का जिक्र कर रहे हैं।

यदि आप इस या नहीं कर सकते मैं निश्चित रूप से पता नहीं है, लेकिन मुझे लगता है कि जी ++ 4.2 के साथ संकलित करने के लिए कोड प्रेरित Parenthese के किसी भी संयोजन के साथ नहीं आ सकता है।

+0

केवल ':: memberf_signature' के बारे में क्या हो सकता है? – user470379

-3

खैर मूल रूप से यह काम नहीं कर सकते हैं (कम से कम मैं कोई रास्ता नहीं जी ++ का उपयोग कर पता); बोर्लैंड सी ++ कंपाइलर का उपयोग करना __closure कीवर्ड होगा।

कारण यह संकलित नहीं करता है, फ़ंक्शनपोइंटर (x86 मशीन पर) का आकार हमेशा < < 32 बिट्स पर रहता है; लेकिन यदि आप कक्षा (इंटरफ़ेस) हस्ताक्षर को इंगित करना चाहते हैं, तो इसका आकार 64 बिट होना चाहिए: इस पॉइंटर के लिए 32 बिट (क्लास इंटरफ़ेस केवल एक बार मेमोरी में है) और वास्तविक फ़ंक्शन के लिए 32 बिट

लेकिन __closure कीवर्ड एक बीसीबी भाषा 'हैक' मानकीकृत नहीं है ...

+0

तथ्य यह है कि सदस्य फ़ंक्शन पॉइंटर्स और फ़ंक्शन पॉइंटर्स अलग-अलग आकार के हैं, मेरे लिए अप्रासंगिक लगते हैं। आम तौर पर, 'लघु' और 'डबल' विभिन्न आकारों के होते हैं, लेकिन आप दोनों के साथ 'typedef' कर सकते हैं। –

+1

'यह' सूचक आमतौर पर पहले, छिपे पैरामीटर के रूप में पारित किया जाता है। मैंने इस पॉइंटर को ऑब्जेक्ट में पॉइंटर में बदलने के लिए 64-बिट पॉइंटर का उपयोग करके किसी भी कंपाइलर के बारे में नहीं सुना है। –

+0

यह बिल्कुल गलत है। यह पॉइंटर आईए -32 लक्ष्य मशीन पर (उदा। एमएससी) ईसीएक्स-रजिस्टर में संग्रहीत है। इस तरह के सिस्टम पर कोई भी सूचक हमेशा 32-बिट होता है। – 0xbadf00d

2

यह मेरे लिए काम करता है:

#include <iostream> 

class foo 
    { 
public: 
    int g (int x, int y) { return x + y ; } 
    } ; 

typedef int (foo::*memberf_pointer)(int, int); 

int main() 
    { 
    foo f ; 
    memberf_pointer mp = &foo::g ; 
    std::cout << (f.*mp) (5, 8) << std::endl ; 
    } 
+0

यह सदस्य फ़ंक्शन पॉइंटर के लिए टाइपिफ़ है। यह काम मेरे लिए भी है, लेकिन मैं इसके बाद नहीं हूं;) – 0xbadf00d

+0

ठीक है, अब मैं देख रहा हूं कि आप क्या चाहते हैं। लेकिन अगर आप इसे बनाने के लिए प्रबंधन करते हैं, तो आप इस टाइपपीफ का उपयोग करने की योजना कैसे बनाते हैं? – TonyK

3

आप गुणों टेम्पलेट उपनाम की 'typedefing' का उपयोग करके आधुनिक सी में लक्ष्य वर्ग को अलग कर सकते हैं ++ (पोस्ट 11)। आप की तरह की तरह लग रहे हैं की जरूरत है: अभी तक घोषणा के बिंदु पर

template<typename T> 
using memberf_pointer = int (T::*)(int, int); 

, इस वाक्य रचना का उपयोग सदस्य कार्य करने के लिए एक सूचक लक्ष्य वर्ग निर्दिष्ट करने की आवश्यकता होगी:

// D is a member function taking (int, int) and returning int 
memberf_pointer<foo> mp = &foo::D; 
बस जिज्ञासा से बाहर
संबंधित मुद्दे