2012-03-24 12 views
6

मैं सोच रहा था कि ऑपरेटर + और/या ऑपरेटर + = ओवरलोड करने पर चाल semantics का उपयोग करने के लिए किस तरह के मामलों को समझ में आता है। भले ही इसे this question में समझाया गया हो, लेकिन कोई यह कैसे कर सकता है, मैं अपने सिर को लपेट नहीं सकता कि मैं ऐसा क्यों करूं। आइए ऑपरेटर + = पर विचार करें। अगर मैं संदर्भ के दाहिने हाथ से गुज़रता हूं और बाईं ओर ऑब्जेक्ट पर उचित परिवर्तन करता हूं, तो वैसे भी कोई अनावश्यक प्रतियां नहीं होती हैं। तो हम एक ही बिंदु पर वापस आते हैं: ऐसे मामले में अर्थशास्त्र को ले जाना फायदेमंद होगा?क्या ऑपरेटर + और/या ऑपरेटर + = के लिए चाल semantics का उपयोग करने के लिए यह समझ में आता है?

+0

ऑपरेटर को अधिभारित करना सामान्य रूप से एक बुरा विचार है। क्योंकि: ** 1) ** यदि यह स्पष्ट रूप से ऐसा करने का एक अच्छा मामला है, तो शायद आपके लिए पहले से ही एक लाइब्रेरी लागू कर रही है। ** 2) ** यदि यह स्पष्ट रूप से ऐसा करने का एक अच्छा मामला नहीं है, तो शायद यह करने के लिए यह एक बहुत बुरा मामला है। – enobayram

+3

@enobayram इसे 'एपेंड' सदस्य फ़ंक्शन बनाता है यदि आप अधिभारित ऑपरेटरों के आसपास घूमते हैं। अब आप अभी भी सवाल का जवाब दे सकते हैं। –

+7

@enobayram, यह बिल्कुल समझ में नहीं आता है। उस तर्क पर, आमतौर पर किसी भी प्रकार का कोड लिखना एक बुरा विचार है। – TonyK

उत्तर

12

हां और नहीं।

ऑपरेटर + =

ले जाएँ अर्थ विज्ञान क्योंकि आप पहले से, बाएं हाथ की ओर तर्क (this) को संशोधित कर रहे हैं ताकि आप पहले से ही समय की सबसे के साथ काम करने संसाधन हैं, सामान्य रूप में operator+= के लिए जरूरी उपयोगी नहीं हैं।

फिर भी, एक अनुकूलन के रूप में, यह इसके लायक हो सकता है। एक std::string कार्यान्वयन की कल्पना करें जिसका डिफ़ॉल्ट कन्स्ट्रक्टर किसी भी स्मृति को आवंटित नहीं करता है। फिर std::string::operator+=(std::string&&) बस आरएचएस से संसाधन चुरा सकता है। या कल्पना करें कि आरएचएस बफर सबकुछ पकड़ने के लिए काफी बड़ा है लेकिन एलएचएस नहीं है, तो यदि आप आरएचएस बफर का उपयोग कर सकते हैं तो आप सुनहरे हैं: बस स्वैप करें और प्रीपेन्ड करें।

तो, यह इसके लायक हो सकता है, लेकिन आपको इसका अध्ययन करना होगा। इसलिए:

  • T& T::operator+=(T const&): हमेशा मौजूद
  • T& T::operator+=(T&&): चाल अर्थ विज्ञान सक्षम करने के लिए जब यह समझ में आता है

ऑपरेटर +

यहाँ यह हमेशा उपयोगी (प्रदान कर रहा है हम कक्षाओं के बारे में बात कर रहे हैं जिसके लिए सैमांतिक्स चल रहे हैं)।

बात यह है operator+ एक अस्थायी पैदा करता है (नीला में से) तो यह आम तौर पर है यह अस्थायी के लिए संसाधनों बनाने के लिए। हालांकि अगर यह उन्हें बनाने के बजाय उन्हें चुरा सकता है, तो यह निश्चित रूप से सस्ता है।

हालांकि, अगर आप सब भार के प्रदान करने की जरूरत नहीं:

  • T operator+(T const&, T const&)
  • T operator+(T&&, T const&)
  • T operator+(T const&, T&&)
  • T operator+(T&&, T&&) (बहुविकल्पी के लिए आवश्यक)

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

inline T operator+(T left, T const& right) { left += right; return left; } 
inline T operator+(T const& left, T right) { right += left; return right; } // commutative 
inline T operator+(T left, T&& right) { left += right; return left; } // disambiguation 

लाभ (4 में से 3 के बजाय) के ज्यादा नहीं है, लेकिन अच्छी तरह से, मैं क्या मैं कर सकते हैं ले लेंगे!

बेशक

, स्ट्रिंग के लिए, operator+ नहीं विनिमेय (यही कारण है कि एक बुरा अधिभार है) है, इसलिए दूसरे अधिभार की वास्तविक क्रियान्वयन एक prepend विधि की आवश्यकता होगी।

EDIT: Move semantics and operator overloading के बाद ऐसा लगता है कि मैं थोड़ा अधिक उत्साही था। बेन वोइट के जवाब से चोरी, हम पाते हैं:

inline T operator+(T left, T const& right) { left += right; return left; } 
inline T operator+(const T& left, T&& right) { right += left; return right; } 

दूसरी ओर, यह केवल विनिमेय के संचालन के लिए काम करने के लिए लगता है, - इस तरह से काम नहीं करता है लेकिन संभवतः / और % को दूसरी ओर अनुकूलित किया जा सकता है ...

+0

बेहतर करें 'दाएं + = बाएं; वापस लौटें; 'लौटने पर इसे' राइट 'के रूप में एक रावल्यू के रूप में मानने के लिए। –

+0

@ जोहान्सचैब-लिटब: क्या मुझे लगता है कि आप अंतिम मामले के बारे में बात कर रहे हैं? मैंने इसके बारे में भी सोचा, और क्या 'टी एंड टी टी :: ऑपरेटर +() और 'अधिभार' के लायक था। –

+0

मैं तीनों मामलों के बारे में बात कर रहा हूं। यदि 'टी' में एक चालक कन्स्ट्रक्टर है, तो आप क्रमशः 'बाएं' या 'दाएं' लौटकर इसका उपयोग कर सकते हैं। चूंकि यह अब आपके कोड के साथ है, अगर 'ऑपरेटर + =' 'टी '' लौटाता है, तो आप हमेशा इसे ले जाने के बजाय पैरामीटर को रिटर्न वैल्यू में कॉपी करेंगे। –

1

यदि आप दो तारों, वैक्टर आदि को जोड़ रहे हैं, तो आप "हिल" नहीं सकते हैं, यह समझ में नहीं आता है। लेकिन यदि आप जोड़ रहे हैं, तो लिंक्ड सूचियों का कहना है, जहां सूची को जोड़ना संभवतः ओ (1) ऑपरेटर है, यदि आप दायीं ओर बलिदान देने के इच्छुक हैं, तो यह समझ में आता है।

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