2011-01-16 4 views
22

मैं सी ++ के बारे में एक पुस्तक पढ़ रहा हूं और ऑपरेटर अधिभार के बारे में अधिक सटीक रूप से पढ़ रहा हूं।सी ++ क्यों असाइनमेंट ऑपरेटर को टालने के लिए एक कॉन्स रेफ वापस करना चाहिए (ए = बी) = सी

const Array &Array::operator=(const Array &right) 
{ 
// check self-assignment 
// if not self- assignment do the copying 
return *this; //enables x=y=z 
} 

रेफरी के बजाय स्थिरांक रेफरी लौटने के बारे में पुस्तक द्वारा प्रदान की व्याख्या इस तरह के रूप (x = y) = z कार्य से बचना है:

उदाहरण का पालन करना है। मुझे समझ में नहीं आता कि हमें इससे क्यों बचना चाहिए। मैं समझता हूं कि x = y का मूल्यांकन इस उदाहरण में पहले किया गया है और चूंकि यह एक कॉन्स्ट संदर्भ देता है = z भाग निष्पादित नहीं किया जा सकता है। पर क्यों?

+3

कौन सी किताब? यह मेरे लिए एक अनावश्यक सावधानी की तरह दिखता है। मैं किसी को लिखने की कल्पना नहीं कर सकता '(x = y) = z' - वे क्यों होंगे? और माता-पिता के बिना, 'x = y = z' को' x = (y = z) 'के रूप में पार्स किया गया है, जो सही समझ में आता है, इसलिए वहां कोई जोखिम नहीं है। –

+1

लेकिन क्यों? यह एक कॉन्स रेफरी क्यों है? इस आदेश में इसे क्यों निष्पादित किया जाता है? 'X' को असाइन क्यों नहीं किया जा सकता है (x = y)? – Lazarus

+16

@antronis: बेहतर सी ++ पुस्तक प्राप्त करें। – ybungalobill

उत्तर

24

(x=y) का अर्थ x.operator=(y) है, जो ऑब्जेक्ट x देता है। इसलिए, (x=y)=z का अर्थ है (x.operator=(y)).operator=(z)। माता-पिता में अभिव्यक्ति xy पर सेट करती है और x लौटाती है, और फिर बाहरी बिट x से z पर सेट करता है। यह y से z पर सेट नहीं करता है जैसा कि आप उम्मीद कर सकते हैं, और अभिव्यक्ति x = y = z करता है।

यह व्यवहार प्रति-अंतर्ज्ञानी है (वे सभी असाइनमेंट के बाद बराबर होना चाहिए, है ना?); एक कॉन्स संदर्भ लौटने से यह असंभव हो जाता है और समस्या से बचा जाता है।

+2

जबकि व्यवहार काउंटर-अंतर्ज्ञानी लगता है, यह "समस्या" नहीं है क्योंकि यह प्रोग्रामर जानबूझकर किया गया है (यही कारण है कि उन्होंने ब्रैकेट का उपयोग किया) – James

+18

कौन सा ('x = y) = z' सेट करने की अपेक्षा करेगा 'y' से' z'? यह बहुत ही समस्याग्रस्त "समस्या" है और सी ++ पुस्तक को इसके खिलाफ सावधानी बरतने में समय नहीं लगाया जाना चाहिए। '(x = 5) = z'' z' को 'z' पर सेट नहीं करता है। –

+0

यदि आप असाइनमेंट होने की अपेक्षा करते हैं (जैसे तुलना है), तो आप उम्मीद करेंगे कि सभी तीन अंत में बराबर होंगे। बेवकूफ, लेकिन एक उचित पहली नज़र व्याख्या। मैं मानता हूं कि इस फ़ॉर्म को आम तौर पर इस्तेमाल नहीं किया जाना चाहिए और पुस्तक में जोर नहीं दिया जाना चाहिए, लेकिन संकलक की मदद करने में मदद करना अच्छा है * जब भी संभव हो तो पैर में शूट न करें =) –

18

इस से बचने की कोई आवश्यकता नहीं है, जब तक कि पुस्तक प्रोग्रामर के लिए लक्षित न हो, आमतौर पर (x=y)=z लिखते हैं जब उनका मतलब x=y=z होता है। व्यावहारिक रूप से, उनके सही दिमाग में कोई भी नहीं लिखता है, इसलिए सावधानी पूरी तरह से अनावश्यक है। यह (x=y).nonConstMember() जैसे कुछ अन्य टेर्स संरचनाओं को भी रोकता है, जो शायद ही कभी लिखते हैं लेकिन यह कुछ संदर्भों में उपयोगी हो सकता है (हालांकि उन्हें अधिक उपयोग नहीं किया जाना चाहिए)।

@ybungalobill सही है, एक बेहतर किताब प्राप्त करें।

+9

+1। एक प्रोग्रामर "गलती से" लेखन '(x = y) = z' एक प्रोग्रामर के रूप में गलती से 'x = y + system (" rm -rf/") लिखने के रूप में संभवतः (और इसके खिलाफ सुरक्षा के लिए आवश्यक) जैसा लगता है, जब उनका मतलब था 'एक्स = y'। –

+0

@j_random_hacker "ओह, गलत विंडो" में संभव लगता है! परिदृश्य ... – Calimo

+1

लेकिन मैंने देखा है कि अगर ((x = y) = z) ... 'जब लेखक का अर्थ था' if ((x = y) == z) ... '। –

10

जहां तक ​​मुझे पता है, असाइनमेंट ऑपरेटर बेवकूफ सी ++ में कॉन्स संदर्भ वापस नहीं करते हैं। मानक प्रकार या तो कॉन्स संदर्भ वापस नहीं करते हैं।

std::string a, b, c; 
(a = b).clear(); // no objection from compiler 

मेरे सभी कस्टम असाइनमेंट ऑपरेटरों ने एक गैर-कॉन्स्ट संदर्भ वापस कर दिया है।

संदेह में, मानक पुस्तकालय की जांच करें। यह निर्दोष नहीं है, लेकिन यह निश्चित रूप से इस तरह की बुनियादी चीजें प्राप्त करता है।

+0

बूस्ट लोक आमतौर पर उत्परिवर्तनीय रेफरी भी लौटते हैं। –

3

मैं अंतर्निहित प्रकारों के व्यवहार को देखता हूं।

अपने स्वयं के प्रकार को परिभाषित करते समय यह बेहतर है कि ऑपरेटरों अंतर्निहित प्रकारों के समान व्यवहार करते हैं। यह आपके कोड में खोदने के बिना अपने वर्गों को आसानी से अपनाने की अनुमति देता है ताकि वे यह देखने के लिए अलग-अलग व्यवहार क्यों कर सकें।

तो अगर हम पूर्णांकों को देखो:

int main() 
{ 
    int x = 5; 
    int y = 6; 
    int z = 7; 

    (x = y) = z; 
    std::cout << x << " " << y << " " << z << "\n"; 
} 

यह y अपरिवर्तित के साथ काम करता है और अपने कोड मैं अपने असाइनमेंट ऑपरेटर उसी तरह काम करने के लिए उम्मीद करेंगे में 7. निर्धारित किये जाने से x। मानक असाइनमेंट ऑपरेटर परिभाषा:

Array& Array::operator=(Array const& rhs) 
{ 
    /* STUFF */ 
    return *this; 
} 

करना चाहिए कि ठीक (यह मानते हुए/* चीज़ें */सही है)।

1

एकमात्र कारण यह है कि मैं देख सकता हूं कि यह पुस्तक सी ++ से सी प्रोग्रामर को समझाने के लिए लिखी गई थी (या एक लेखक जिसका सी समझ सी ++ समझ से बेहतर है)। क्योंकि सी प्रोग्रामर के लिए, अभिव्यक्ति (x = y) = z अंतर्निहित प्रकारों के लिए अमान्य है, और संभवतः वह अपने उपयोगकर्ता-परिभाषित प्रकारों के साथ समान व्यवहार प्राप्त करने का प्रयास करेगा।

हालांकि, सी और सी ++ अलग-अलग भाषाएं हैं, और सी ++ में अभिव्यक्ति (x = y) = z अंतर्निहित प्रकारों के लिए भी मान्य है। इसलिए यदि आप अपने उपयोगकर्ता द्वारा परिभाषित प्रकारों के लिए एक ही व्यवहार करना चाहते हैं, तो आपको operator = में एक गैर-कॉन्स्ट संदर्भ वापस करना चाहिए।

मैं आपको एक बेहतर पुस्तक प्राप्त करने की सलाह दूंगा, जो सी और सी ++ के बीच भ्रम पैदा नहीं करता है। वे एक ही लंगेज नहीं हैं, भले ही वे एक सामान्य आधार से प्राप्त हों।

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