c++ - क्या ऐसी स्थितियां हैं जब स्व-असाइनमेंट उपयोगी है?




assignment-operator (2)

एल्गोरिदम हैं जहां यह हो सकता है।

  1. आप जानते हैं कि lhs और rhs समान हो सकते हैं, लेकिन चेक की तुलना में असाइनमेंट को करना सरल है। जैसे, a = std::min(a,b); - if (a > b) a = b; तुलना में सरल और शायद समझना आसान है if (a > b) a = b; - अब समान चीजों के अधिक जटिल उदाहरणों पर विचार करें।

  2. आप नहीं जानते कि क्या lhs और rhs समान हो सकते हैं, क्योंकि वे कहीं और से पारित किए गए हो सकते हैं।

ये एल्गोरिदम जहां यह हो सकता है असामान्य नहीं हैं।

यह आमतौर पर ज्ञात है कि असाइनमेंट ऑपरेटर को लागू करते समय किसी को स्व-असाइनमेंट के खिलाफ सुरक्षा करनी होती है, कम से कम जब क्लास में गैर-पीओडी सदस्य होते हैं। आमतौर पर यह (या इसके बराबर है):

Foo& operator=(const Foo& other)
{
  if (&other == this)
     return *this;
  ... // Do copy
}

स्व-असाइनमेंट सुरक्षा को स्वचालित रूप से सम्मिलित नहीं करने के कारण क्या थे? क्या ऐसे मामले हैं जब स्व-असाइनमेंट कुछ गैर-तुच्छ और व्यावहारिक रूप से उपयोगी है?

Foo& operator=(const Foo& other)
{
  if (&other == this)
  {
    // Do something non-trivial
  }
  else
  {
    // Do copy
  }
  return *this;
}

अब तक के उत्तरों और चर्चा को संक्षेप में प्रस्तुत करना

ऐसा लगता है कि गैर-तुच्छ स्व-असाइनमेंट कभी भी उपयोगी नहीं हो सकता है। कुछ तार्किक त्रुटियों का पता लगाने के लिए एक ही विकल्प प्रस्तावित किया गया था। लेकिन काफी वैध स्व-असाइनमेंट मामले हैं जैसे a = std::min(a, b) , इसलिए भी यह विकल्प अत्यधिक संदिग्ध है।

लेकिन एक तुच्छ स्व-कार्य के दो संभावित कार्यान्वयन हैं:

  1. कुछ भी न करें &other == this अगर &other == this । हमेशा काम करते हैं, हालांकि एक अतिरिक्त शाखा के कारण नकारात्मक प्रदर्शन प्रभाव पड़ सकता है। लेकिन एक उपयोगकर्ता-निर्धारित असाइनमेंट ऑपरेटर में परीक्षण लगभग हमेशा स्पष्ट रूप से बनाया जाना चाहिए।
  2. प्रत्येक सदस्य को स्वयं कॉपी करें। यह डिफ़ॉल्ट रूप से किया जाता है। यदि सदस्य डिफ़ॉल्ट असाइनमेंट ऑपरेटर्स का उपयोग करते हैं, तो यह तेज़ हो सकता है, क्योंकि अतिरिक्त ब्रांचिंग की आवश्यकता नहीं है।

मैं अभी भी यह नहीं देखता कि C ++ मानक यह गारंटी क्यों नहीं दे सकता कि उपयोगकर्ता-निर्धारित असाइनमेंट ऑपरेटर &other != this । यदि आप कोई शाखा नहीं चाहते हैं, तो डिफ़ॉल्ट ऑपरेटर का उपयोग करें। यदि आप ऑपरेटर को फिर से परिभाषित कर रहे हैं, तो कुछ परीक्षण की आवश्यकता है ...


मुझे यह स्वीकार करना चाहिए कि मैंने इस तरह के सामान्य ज्ञान के बारे में कभी नहीं सुना है। गैर-पीओडी वस्तुओं के लिए, कॉपी कंस्ट्रक्टर और असाइनमेंट ऑपरेटर को अक्षम करने के साथ उनकी नकल करने के लिए एक अधिक सख्त दृष्टिकोण है। ताकि आपको समस्या न हो।

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

आपके प्रश्न के लिए, यदि आपको केवल स्वचालित "स्व-असाइनमेंट सुरक्षा" कुछ भी करने की आवश्यकता नहीं है, तो एक तरह से पहले से ही है। यदि आप असाइनमेंट ऑपरेशन को स्पष्ट रूप से परिभाषित नहीं करते हैं और संकलक को स्वचालित रूप से उपयोग करने देते हैं, तो आत्म-असाइनमेंट को चालू करने के बाद नो-ऑप बन सकता है।

उदाहरण के लिए, निम्न कोड:

class A {
    int a;
    double b;
};

A& foo(A& input)
{
    return (input = input);
}

संकलित किया गया है (gcc 4.9, -O2):

_Z3fooR1A:
    .cfi_startproc
    movq    %rdi, %rax
    ret
    .cfi_endproc

जो किसी चीज की नकल न करे।





assignment-operator