2012-07-25 23 views
10

संभव डुप्लिकेट:
Functions with const arguments and Overloadingओवरलोडिंग रिज़ॉल्यूशन के लिए प्रयुक्त फ़ंक्शन तर्कों में कॉन्स्ट क्वालीफायर क्यों हैं?

मैं बहुत अधिक भार और स्थिरांक घोषणा नियमों से उलझन में हूँ। यहां दो चीजें हैं जो मुझे पहेली करती हैं शायद आप मेरे सिर में गहरी गलतफहमी खोजने में मेरी मदद कर सकते हैं जिसके परिणामस्वरूप वे मुझे परेशान कर रहे हैं। ;)

सबसे पहले मुद्दा:

मेरे संकलक इस अनुमति देता है:

void f(int & x) { 
    std::cout << "plain f" << std::endl; 
} 
void f(const int & x) { 
    std::cout << "const f" << std::endl; 
} 

लेकिन निम्नलिखित एक संकलन त्रुटि (समारोह पहले से ही एक शरीर है) का कारण बनता है:

void f(int x) { 
    std::cout << "plain f" << std::endl; 
} 
void f(const int x) { 
    std::cout << "const f" << std::endl; 
} 

कौन सा मुझे लगता है समझ में आता है क्योंकि मैंने सोचा था कि कंस्ट्रल केवल कंपाइलर को बताने के लिए था कि वस्तु पारित की जा रही है और दूसरे मामले में इसे किसी भी तरह कॉपी नहीं किया गया है। लेकिन अगर यह सही है तो मैं कॉन्स्ट का उपयोग करके कार्यों को अधिभार क्यों कर सकता हूं?

दूसरे शब्दों में, क्यों करता है, तो मैं इस तरह संकलन संस्करण का उपयोग और कार्यों फोन:

int x1 = 5; 
    const int x2 = 5; 
    f(x1); 
    f(x2); 

मैं मिलता है "सादे च" और "स्थिरांक च" "स्थिरांक च" दो बार के बजाय? जाहिर है, अब मैं कंपाइलर को बताने के लिए भी कॉन्स्ट का उपयोग कर रहा हूं जो कॉल करने के लिए काम करता है न केवल संदर्भ बदलता है। यह अधिक भ्रमित हो जाता है क्योंकि अगर मैं "सादा" संस्करण को हटा देता हूं तो यह ठीक काम करता है और "कॉन्स" संस्करण को दो बार कॉल करता है।

अब मेरा वास्तविक प्रश्न क्या है? मैं जानना चाहता हूं कि इस व्यवहार के पीछे क्या विचार हैं क्योंकि अन्यथा इसे याद रखना बहुत मुश्किल है।

+0

फ़ंक्शन पैरामीटर पर शीर्ष स्तर 'const' qualifiers फ़ंक्शन के हस्ताक्षर को निर्धारित करते समय _removed_ हैं। 'शून्य एफ (int)' और 'शून्य एफ (कॉन्स int)' एक ही फ़ंक्शन का संदर्भ लें। ओवरलोड रिज़ॉल्यूशन के लिए शीर्ष स्तर 'const' का उपयोग नहीं किया जाता है। व्युत्पन्न प्रकार के नीचे 'const' आगे (जैसे कि 'const int' 'में) फ़ंक्शन पैरामीटर के प्रकार और इसलिए फ़ंक्शन हस्ताक्षर को प्रभावित करते हैं। –

+0

यह भी देखें: http://stackoverflow.com/questions/4212932/defining-a- कार्यक्षमता-with- अलग-अलग हस्ताक्षर –

+0

@ चार्ल्सबैली लिंक के लिए धन्यवाद। किसी तरह मुझे उनको नहीं मिला, क्षमा करें। – Sarien

उत्तर

1

मैंने सोचा था कि स्थिरांक केवल वहाँ संकलक कि किया जा रहा वस्तु पारित कर दिया बदला नहीं है यह बताने के लिए था और दूसरे मामले में यह वैसे भी नकल की जाती है

आप सही हैं। क्योंकि दूसरे मामले में यह किसी भी तरह की प्रतिलिपि बनाई गई है, और इसलिए const कॉलर में कोई फर्क नहीं पड़ता है, मानक परिभाषित करता है कि void f(const int x) और void f(int x) समान हस्ताक्षर है। इसलिए वे टकराते हैं, आप एक ही समारोह को दो बार परिभाषित करने की कोशिश कर रहे हैं।

क्योंकि पहले मामले में यह वैसे भी कॉपी नहीं है, void f(const int &x) और void f(int &x)अलग हस्ताक्षर किया है। इसलिए वे अधिभार।

अपने पहले मामले में, यह, x2 तर्क के रूप में साथ f की int& संस्करण कॉल करने के लिए, क्योंकि वह दृष्टि में कोई स्पष्ट कलाकारों के बिना एक स्थिरांक वस्तु के लिए एक गैर स्थिरांक संदर्भ बनाएगा मना किया है। ऐसा करने से कॉन्स सिस्टम के उद्देश्य को हराया जाता है (जो कि यदि आप कॉन्स्ट-सुरक्षा तोड़ना चाहते हैं, तो आपको एक कलाकार के साथ स्पष्ट रूप से ऐसा करना होगा)। इसलिए संदर्भ पैरामीटर के साथ कार्यों के कॉन्स्ट- और गैर-कॉन्स ओवरलोड को समझना समझ में आता है।

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

+0

तो शायद मेरा प्रश्न नीचे उबलता है: मैं कॉन्स्टलेस फ़ंक्शन का उपयोग क्यों करना चाहूंगा (कॉल करते समय)? थोड़ा सा विस्तार करने के लिए: जब मुझे f (int const और x) है तो मुझे f (int और x) क्यों कॉल करना चाहिए? ऐसा लगता है कि किसको बुलाया जाता है और पूरी तरह भ्रमित होता है। – Sarien

+0

मुझे लगता है कि यह इस तथ्य से संबंधित है कि मेरे सिर में "कॉन्स्ट" मुझे फ़ंक्शन के व्यवहार के बारे में कुछ बताता है (इस संदर्भ को नहीं बदलता है) और अब इसका उपयोग करने के लिए _which_ फ़ंक्शन का निर्णय लेने के लिए उपयोग किया जा रहा है। – Sarien

+0

@ कॉरपोरल टच: आप * कॉन्स्ट तर्क के साथ गैर-कॉन्स्ट फ़ंक्शन को कॉल नहीं कर सकते हैं, क्योंकि इसे 'शून्य एफ (int & x) {x = 6;} 'जैसे कुछ करने की अनुमति है। यही कारण है कि जब आप इसे 'x2' पास करते हैं तो 'f (const int और x)' अधिभार का चयन किया जाता है। जब आप इसे 'x1' पास करते हैं, तो गैर-कॉन्स अधिभार का चयन किया जाता है, क्योंकि तर्क के रूप में गैर-कॉन्स लैवल्यू प्रदान करके, आप इसे अपने चर को संशोधित करने की अनुमति दे रहे हैं। असल में आपका फ़ंक्शन बॉडी कुछ भी संशोधित नहीं करता है, इसलिए इस मामले में, यह देखना मुश्किल है कि अंतर क्यों मायने रखता है। –

4

n3337 13,1

[नोट: 8.3.5 में विनिर्दिष्ट है, समारोह घोषणाओं है कि बराबर पैरामीटर घोषणाओं एक ही समारोह की घोषणा और इसलिए अतिभारित नहीं किया जा सकता: केवल उपस्थिति या अनुपस्थिति

में ffer

- पैरामीटर घोषणाएं कि डी 3 कॉन्स और/या अस्थिर समकक्ष हैं। यही है, प्रत्येक पैरामीटर प्रकार के लिए कॉन्स और अस्थिर प्रकार-विनिर्देशों को अनदेखा किया जाता है जब यह निर्धारित करता है कि कौन सा फ़ंक्शन घोषित, परिभाषित किया गया है या कहा जाता है। [ उदाहरण:

typedef const int cInt; 
int f(int); 
int f(const int); // redeclaration of f(int) 
int f(int) { /* ... */ } // definition of f(int) 
int f(cInt) { /* ... */ } // error: redefinition of f(int) 

- अंत उदाहरण] केवल स्थिरांक और पैरामीटर प्रकार specifica- tion इस फैशन में अनदेखी कर रहे हैं की सबसे बाहरी स्तर पर अस्थिर प्रकार-विनिर्देशक; एक पैरामीटर प्रकार विनिर्देशन के भीतर दफन किए गए कॉन्स और अस्थिर प्रकार-विनिर्देशक महत्वपूर्ण हैं और ओवरलोडेड फ़ंक्शन घोषणाओं को अलग करने के लिए उपयोग किए जा सकते हैं। विशेष रूप से, किसी भी प्रकार के टी, "टी के लिए सूचक," "पॉइंटर टू कॉन्स्ट टी," और "पॉइंटर टू अस्थिर टी" को विशिष्ट पैरामीटर प्रकार माना जाता है, जैसे कि "टी के संदर्भ में," "कॉन्स्ट टी के संदर्भ" और "अस्थिर टी के संदर्भ में।"

+0

मुझे अभी भी इस व्यवहार के कारण में दिलचस्पी होगी क्योंकि यह कॉन्स के लिए एक भ्रमित डबल अर्थ प्रतीत होता है। (मैं जानना चाहता हूं, इसे मानक में क्यों परिभाषित किया गया है)। – Sarien

+2

@CorporalTouchy: जब आप मान द्वारा पैरामीटर पास करते हैं तो आप एक प्रति बनाते हैं। चाहे वह प्रतिलिपि 'कॉन्स्ट' है, कॉलिंग कोड के व्यवहार पर कोई असर नहीं है, इसलिए कॉलिंग पक्ष पर उनके बीच अंतर करने का कोई कारण नहीं है। –

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

  • कोई संबंधित समस्या नहीं^_^