2009-07-13 9 views
5

क्या सूचकांक के लिए पॉइंटर और सामान्य सूचक के बीच कोई अंतर है? जब स्टैंड स्टैंड अकेले कार्यों के लिए कॉन्स क्वालीफायर का उपयोग करने के लिए उपयुक्त है?पॉइंटर को बनाम सामान्य सूचक (कार्यों के लिए)

#include <iostream> 
using namespace std; 

int sum(int x, int y) { return x + y; } 
typedef int sum_func(int, int); 

int main() 
{ 
    const sum_func* sum_func_cptr = &sum; // const function 
    sum_func* sum_func_ptr = &sum;  // non-const function ? 

    // What is the difference between sum_func_cptr and sum_func_ptr 

    int x = sum_func_cptr(2, 2); 
    cout << x << endl; 

    int y = sum_func_ptr(2, 2); 
    cout << y << endl; 

    sum_func_cptr = 0; 
    sum_func_ptr = 0; 

    return 0; 
}

जी ++ कोई चेतावनी देता है:

मैं मेरे सवाल का वर्णन करने के लिए छोटा नमूना लिखा था। यही कारण है कि मैं पूछता हूं।

उत्तर

12

आपका कोड सी ++ 03 के संबंध में बीमार का गठन है। आप कभी भी एक कॉन्स (या अस्थिर) योग्य फ़ंक्शन प्रकार बना सकते हैं। जब भी आप करते हैं, आपका कार्यक्रम खराब हो जाता है।

यह नियम has been changed सी ++ 1x के लिए, संकलक को const/volatile को अनदेखा करने के लिए। सी ++ कंपाइलर आमतौर पर सी ++ 03 मोड में भी इस नियम को लागू करेंगे। इस प्रकार, निम्नलिखित दो एक ही फ़ंक्शन को दो बार परिभाषित करेंगे, और संकलन त्रुटि में परिणाम होंगे।

typedef void Ft(); 


void f(Ft const*) { } 
void f(Ft *) { } // another definition! 

यहां मेरे दावे का सबूत है। सी ++ 03, 8.3.5/1

एक सीवी-क्वालीफायर-सेक केवल एक nonstatic सदस्य समारोह के लिए समारोह प्रकार का हिस्सा होगा, समारोह प्रकार है जो करने के लिए सदस्य के लिए एक सूचक संदर्भित करता है, या उच्च-स्तरीय समारोह प्रकार एक कार्य typedef घोषणा के। फ़ंक्शन घोषणाकर्ता में सीवी-क्वालीफायर-सेक का प्रभाव फ़ंक्शन प्रकार के शीर्ष पर सीवी-योग्यता जोड़ने जैसा नहीं है, यानी, यह एक सीवी-योग्य फ़ंक्शन प्रकार नहीं बनाता है। वास्तव में, यदि किसी भी समय किसी प्रकार के निर्धारण में सीवी-योग्यता कार्य प्रकार बनता है, तो कार्यक्रम खराब हो जाता है।

यहाँ सी ++ 1x, के लिए है कि पाठ 8.3.5/7 n2914 है:

एक सीवी-quali फाई एर-सेक केवल एक गैर स्थिर सदस्य समारोह, समारोह प्रकार के लिए समारोह प्रकार का हिस्सा हो जाएगा जिसके लिए सदस्य के लिए एक सूचक संदर्भित करता है, या फ़ंक्शन टाइपपीफ घोषणा के शीर्ष-स्तरीय फ़ंक्शन प्रकार को संदर्भित करता है। फ़ंक्शन घोषणाकर्ता में एक सीवी-क्वालिफ़ी-सीईसी का ई एफएफ ईटीटी फ़ंक्शन प्रकार के शीर्ष पर सीवी-क्वालिफ़िकेशन जोड़ने जैसा नहीं है। बाद के मामले में, सीवी-क्वाली फायर को नजरअंदाज कर दिया जाता है।

उपरोक्त कहता है कि नीचे वैध है, हालांकि, और फ़ंक्शन के लिए फ़ंक्शन प्रकार बनाता है जो एक कॉन्स्ट सदस्य फ़ंक्शन घोषित कर सकता है।

typedef void Ft() const; 
struct X { Ft cMemFn; }; 
void X::cMemFn() const { } 
+0

अरे, उस मानक के विशेषज्ञ के बारे में मैं बात कर रहा था। : पी – GManNickG

+0

हे, मैं मानक ग्रंथों के साथ teh n00b हूँ। लेकिन मुझे खुशी है कि आपको विश्लेषण पसंद है :) –

+0

मैंने सी ++ 98 मानक पढ़ा है। यही कारण है कि मैं इसे नहीं मिला। –

1

मुझे लगता है कि आप का मतलब है,
sum_func* const sum_func_cptr बजाय const sum_func* sum_func_cptr

sum_func* const sum_func_cptr = &sum; 
sum_func* const sum_func_cptr = &sum_new; // will not compile. 
// whereas, 
const sum_func* sum_func_cptr = &sum; // will compile 
const sum_func* sum_func_cptr = &sum_new; // will compile. 
sum_func* sum_func_cptr = &sum; // will compile 
sum_func* sum_func_cptr = &sum_new; // will compile. 

-जगानाथ।

+0

नहीं। मेरा मतलब था कि मैंने जो लिखा था। –

+1

@ jia3ep: फिर आपने अपना शीर्षक और विवरण गलत लिखा। "एक्स को पॉइंटर एक्स" का अर्थ है "एक्स * कॉन्स"; जबकि "पॉइंट टू कॉन्स एक्स" का अर्थ है "कॉन्स एक्स *"। आपको इसे पहले सही करना चाहिए। – newacct

+0

मैंने शीर्षक और विवरण तय कर दिया है। –

6

अकेले स्टैंड स्टैंड परिभाषा के आधार पर हैं। इसलिए एक कॉन्स और गैर-कॉन्स फ़ंक्शन पॉइंटर के बीच कोई अंतर नहीं है।

+0

क्या मानक में कुछ जानकारी है जो स्टैंड अकेले कार्यों के लिए क्वालीफायर को अनदेखा करती है। मुझे नहीं मिल रहा –

+0

मुझे पता नहीं है कि इसके लिए मानक में कुछ भी है या नहीं। – Naveen

+0

मैंने अपने जवाब में अपना सर्वश्रेष्ठ प्रदर्शन किया लेकिन मुझे लगता है कि कुछ बेहतर है, जैसे कि यह स्पष्ट रूप से बताता है कि 'फ़ंक्शन हैं'। – GManNickG

0

एक दिलचस्प तरफ के रूप में, सदस्य फ़ंक्शंस पर पॉइंटर्स पर उपयोग किए जाने पर भी कॉन्स्ट विनिर्देश का प्रभाव प्रतीत नहीं होता है।

#include <iostream> 
using namespace std; 

class Foo { 
public: 
    int sum(int x, int y) { 
    _x = x; 
    _y = y; 
    return x + y; 
    } 
private: 
    int _x; 
    int _y; 
}; 

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

int main() 
{ 
    Foo f; 
    const sum_func sum_func_cptr = &Foo::sum; // const pointer 
    sum_func sum_func_ptr = &Foo::sum;  // non-const pointer 

    int x = (f.*sum_func_cptr)(2, 2); 
    cout << x << endl; 

    int y = (f.*sum_func_ptr)(2, 2); 
    cout << y << endl; 

    const sum_func* sum_func_cptr_cptr = &sum_func_cptr; 
    sum_func* sum_func_ptr_ptr = &sum_func_ptr; 

    x = (f.**sum_func_cptr_cptr)(2, 2); 
    cout << x << endl; 

    y = (f.**sum_func_ptr_ptr)(2, 2); 
    cout << y << endl; 

    return 0; 
} 
0

मुझे लगता है कि पिछले उत्तरों में मूलभूत गलतफहमी हुई है।

const sum_func sum_func_cptr = &Foo::sum; // const pointer 

इसका मतलब है कि sum_func_cptr एक समारोह के लिए एक निरंतर सूचक है कि आप एक गैर स्थिरांक सदस्य समारोह के साथ प्रारंभ कर सकते हैं, लेकिन यदि आप किसी अन्य कार्य करने के लिए बात करने के लिए बाद में इसे बदल नहीं सकते, क्योंकि const संदर्भित करता है परिवर्तनीय करने के लिए। यह समतुल्य है:

sum_func const sum_func_cptr = &Foo::sum; // const pointer 

क्या आप सहमत नहीं हैं? :-)

-Paolo

+0

कोई कॉन्स्ट-योग्य फ़ंक्शन प्रकार नहीं हैं। तो 'const sum_func stuff = & foo :: sum; 'कोई अर्थ नहीं है, क्योंकि मेरे उत्तर में मानक का उद्धरण कहता है। यह 'sum_func * const sum_func_cptr = और Foo :: sum;' (* यह * एक कॉन्स्ट फ़ंक्शन पॉइंटर है) कहने के लिए मान्य नहीं होगा, क्योंकि आप फ़ंक्शन पॉइंटर को सदस्य फ़ंक्शन पॉइंटर असाइन करने का प्रयास करते हैं। आपको 'sum_func Foo :: * const sum_func_cptr = & Foo :: sum;' करना होगा। –

+0

मैंने पिछली पोस्ट को एक उदाहरण के रूप में लिया था। यह नए प्रकार "sum_func" को पॉइंटर-टू-सदस्य-फ़ंक्शन के रूप में परिभाषित करता है: टाइपपीफ int (Foo :: * sum_func) (int, int); मेरा मुद्दा यह था कि "sum_func" में जोड़ा गया "const" इसे "पॉइंटर-टू-कॉन्स्ट-सदस्य-फ़ंक्शन" में परिवर्तित नहीं करता है। सचमुच, मुझे यह टाइपिफ़ लिखने के लिए भी पता नहीं है। और मुझे नहीं पता था कि आप अकेले फ़ंक्शन प्रकारों को परिभाषित कर सकते हैं, केवल फ़ंक्शंस के लिए पॉइंटर्स। – Paolo

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