2012-10-03 30 views
11

मैं एक ही पैरामीटर सूची के साथ दो बार एक ऑपरेटर अधिभारित करता हूं। लेकिन अलग वापसी प्रकार के साथ:सी ++ ओवरलोड ऑपरेटर दो बार, एक रिटर्न गैर-कॉन्स्ट संदर्भ और अन्य कॉन्स्ट संदर्भ, वरीयता क्या है?

T& operator()(par_list){blablabla}  
const T& operator()(par_list){blablabla} 

तो जब मैं() ऑपरेटर, जो समारोह क्या वरीयता या स्थिति के आधार पर कहा जा सकता है फोन कर रहा हूँ? मुझे पता है कि यदि मैं कॉन्स्ट फ़ंक्शन के तहत कॉल() को कॉल करता हूं तो इसे टी & एक होना चाहिए।

मैं उत्सुक हूं कि सी ++ ऐसी स्थिति से कैसे निपटता है और डिफ़ॉल्ट वरीयता कैसे काम करती है।

धन्यवाद

+1

शब्द है * अधिभार *, और कोई। – chris

+2

सी ++ रिटर्न प्रकार से ओवरलोड को अस्वीकार करता है। कोई भी 'क्या कर सकता/चाहिए' में जा सकता है, लेकिन इससे कोई फर्क नहीं पड़ता। एक चाल है जब रिटर्न प्रकार का आधार होता है तो विधि को स्थिर करना होता है, क्योंकि इसे अधिभारित किया जा सकता है। मेरी याददाश्त है कि कॉन्स्ट विधि को प्राथमिकता दी जाती है, गैर-कॉन्स को कॉन्स्ट कॉल कहा जाता है, यह कानूनी नहीं होगा। – Joe

उत्तर

21

ये फ़ंक्शन एक दूसरे को अधिभारित नहीं करते हैं; उनके पास समान हस्ताक्षर हैं, और इसलिए एक ही फ़ंक्शन को फिर से परिभाषित करने का प्रयास, जो एक त्रुटि है। वापसी का प्रकार किसी फ़ंक्शन के हस्ताक्षर का हिस्सा नहीं है। फ़ंक्शन को अधिभारित करने के लिए, आपको एक ही नाम के साथ एक दूसरा फ़ंक्शन घोषित करना होगा, लेकिन विभिन्न पैरामीटर या const/volatile क्वालीफायर - यानी, फ़ंक्शन पर क्वालीफायर, रिटर्न प्रकार नहीं।

(वे एक दूसरे को ओवरराइड नहीं करते हैं; ओवरराइडिंग कक्षाओं को उनके मूल वर्गों के आभासी कार्यों में क्या किया जाता है)।

एक सदस्य फ़ंक्शन के const और गैर-const ओवरलोड को परिभाषित करना आम बात है;

T& operator()(par_list){blablabla} 
const T& operator()(par_list) const {blablabla} 
           ^^^^^ 

अब पहले बुलाया जाएगा यदि आप एक गैर const वस्तु को () लागू होते हैं, और एक const वस्तु पर दूसरा: const अधिभार, न सिर्फ वापसी प्रकार समारोह const घोषित करना चाहिए। उदाहरण के लिए:

Thingy nc; 
Thingy const c; 

nc(); // calls the first (non-const) overload 
c(); // calls the second (const) overload 
+0

@ डेविडरोड्रिगुएज़-ड्राईबीस: ठीक है, मुझे "हस्ताक्षर" का एहसास नहीं हुआ रिटर्न प्रकार शामिल था। क्या "बिट्स जो निर्धारित करते हैं कि कौन से ओवरलोड को चुनने के लिए" आधिकारिक शब्द है? –

+0

@ डेविडरोड्रिगुएज़-ड्राईबीस शायद आप इसे स्पष्ट कर सकते हैं क्योंकि ऐसा लगता है कि सी ++ 03 के बाद से बदल गया है। '§1.3.18' टेम्पलेट कार्यों का संदर्भ लेता है। लेकिन गैर टेम्पलेट (मुफ्त या सदस्य) कार्यों के लिए प्रविष्टियां वापसी मानों का कोई उल्लेख नहीं करती हैं। टेम्पलेट फ़ंक्शन विशेषज्ञता के लिए न तो प्रविष्टियां करें। – juanchopanza

+0

@juanchopanza: आप सही हैं, टिप्पणी को हटा रहे हैं। माइक, मानक की एक सावधानीपूर्वक पुनरीक्षण से संकेत मिलता है कि फ़ंक्शन टेम्पलेट्स (जुआंचो के उल्लेख के रूप में) वापसी प्रकार हस्ताक्षर का हिस्सा है। नियमित कार्यों के लिए हस्ताक्षर में रिटर्न प्रकार शामिल नहीं होता है। सी ++ 03 में एक फुटनोट है: * फ़ंक्शन हस्ताक्षर में रिटर्न टाइप शामिल नहीं है, क्योंकि यह ओवरलोड रिज़ॉल्यूशन में भाग नहीं लेता है। * उत्तर में भ्रम शुरू करने के लिए खेद है :) –

3

आप वापसी प्रकार के आधार पर एक समारोह/विधि ओवरलोड नहीं कर सकते। मैं संकलक से यहां एक त्रुटि फेंकने की उम्मीद करता हूं। आप क्या कर सकते विधि ही निर्दिष्ट एक const पद्धति के रूप में,

const T& operator()(par_list) const {blahblah} 

का उपयोग कर const क्वालीफायर न केवल इसका मतलब है कि यह एक const रिसीवर पर कहा जा सकता है, लेकिन यह भी अधिभार संकल्प में प्रयोग किया जाता है। ऐसा इसलिए होता है क्योंकि यह विधि को पारित होने वाले अंतर्निहित *this पैरामीटर को प्रभावित करता है; const विधि पर const क्वालीफायर का उपयोग करती है, और const क्वालीफायर ओवरलोड रिज़ॉल्यूशन के दौरान खाते में लिया जाता है।

1

तरह से आप अपने ऑपरेटरों को परिभाषित, कोई रास्ता नहीं संकलक तय कर सकते हैं जो ऑपरेटर() कॉल करने के लिए। कार्यों (और ऑपरेटरों) का अधिभार केवल तर्कों के प्रकार पर किया जा सकता है, कभी भी रिटर्न प्रकार पर नहीं। और वास्तव में, जैसे ही आप दूसरे को परिभाषित करते हैं, संकलन में आपको एक त्रुटि होगी, संकलक यह मानते हुए कि आप एक ही फ़ंक्शन/ऑपरेटर को फिर से परिभाषित कर रहे हैं।

हालांकि, निम्नलिखित सामान्य (और शायद तुम्हारे पास क्या है) है:

T& operator()(par_list){blablabla} 
const T& operator()(par_list) const {blablabla} 

इस अतिरिक्त तर्क सूची के बाद "स्थिरांक" मौजूद है क्योंकि आप को परिभाषित कर रहे गैर स्थिर सदस्य कार्य करता है और सदस्य कार्यों एक अंतर्निहित है छुपा तर्क: वर्ग के उदाहरण के लिए "यह" सूचक। वहां "कॉन्स" कीवर्ड इंगित करता है कि क्या यह छुपा सूचक एक कॉन्स उदाहरण है या नहीं।यह तर्क ओवरलोडिंग रिज़ॉल्यूशन में भाग लेता है और यह इस मामले में है कि संकलक का उपयोग करने के लिए ऑपरेटर का कौन सा संस्करण चुनने के लिए उपयोग किया जाता है।

तो:

class A { 
    T& operator()() { ... } 
    const T& operator()() const { .... } 
}; 

A a; 
const A& ca(a); 
a(); -> returns a T& 
ca(); -> returns a const T&