2011-03-28 14 views
11

पुस्तक में सीलोडिंग सी ++ प्राइमर में सी-शैली चरित्र सरणी के लिए एक कोड है, और यह दिखाता है कि = ऑपरेटर को 15.3 ऑपरेटर = में ओवरलोड कैसे करें।ऑपरेटर = सी ++

String& String::operator=(const char *sobj) 
{ 
    // sobj is the null pointer, 
    if (! sobj) { 
     _size = 0; 
     delete[] _string; 
     _string = 0; 
    } 
    else { 
     _size = strlen(sobj); 
     delete[] _string; 
     _string = new char[ _size + 1 ]; 
     strcpy(_string, sobj); 
    } 
    return *this; 
} 

अब मैं क्यों एक संदर्भ String & जब इस कोड के नीचे एक ही काम करता है वापस जाने के लिए की जरूरत है पता करने के लिए, किसी भी समस्या के बिना चाहते हैं:

void String::operator=(const char *sobj) 
{ 
    // sobj is the null pointer, 
    if (! sobj) { 
     _size = 0; 
     delete[] _string; 
     _string = 0; 
    } 
    else { 
     _size = strlen(sobj); 
     delete[] _string; 
     _string = new char[ _size + 1 ]; 
     strcpy(_string, sobj); 
    } 

} 
  • कृपया मदद।
+3

ध्यान दें कि पुस्तक में प्रस्तुत के रूप में समाधान अपवाद सुरक्षित नहीं है (और ऐसा करने के लिए वास्तव में * सरल होगा, मैं वास्तव में समझ में नहीं आता कि उन्होंने क्यों नहीं किया)। –

उत्तर

20

यह निम्न मुहावरा समर्थन करता है:

String a, b; 
const char *c; 

// set c to something interesting 

a = b = c; 

इस काम करने के लिए, b = c एक उपयुक्त वस्तु या संदर्भ a को आवंटित करने के लिए लौट जाना चाहिए के लिए; यह वास्तव में a = (b = c) है C++ ऑपरेटर प्राथमिकता नियमों के अनुसार।

यदि आप सूचक this वापस कर देंगे, तो आपको a = *(b = c) लिखना होगा, जो इच्छित अर्थ व्यक्त नहीं करता है।

+1

अब, वह एक लाइनर था - आप उस पुस्तक को क्यों लिखते हैं। धन्यवाद। मेरा जवाब मिला। – Sadique

+0

मुझे इस जवाब को स्वीकार करने के लिए 9 मिनट के लिए 'प्रतीक्षा' करना होगा !!!!!! – Sadique

+1

@ एसीएम: यह सही है, आपको तब तक इंतजार करना पड़ेगा जब तक कि हर किसी को मुझे गलत साबित करने का मौका न हो। –

0

ऑपरेटर से लौटने = तो आप चीजों को चेन कर सकते हैं। यहाँ तार के बिना देखें:

x = y = 2; 

है कि रेखा की y=2 हिस्सा देता है 2. इसी तरह एक्स एक मूल्य हो जाता है। यदि op = शून्य लौटा, तो आप श्रृंखला = संचालन नहीं कर सका।

3

कन्वेंशन।

a = b = c; 

या इस:

if (foo = come_function()) { 
    // use foo here 
} 
+0

+1, मैं उसे भूल गया। संक्षेप में, यह सम्मेलन आपको सभी बंदूक-उद्देश्य वाली पैर शक्ति देता है जो सी ++ प्रोग्रामर प्यार करते हैं;) –

+0

ध्यान दें कि बाद वाला एक खराब शैली है और इससे बचा जाना चाहिए। –

+0

ध्यान दें कि उत्तरार्द्ध खराब शैली है या नहीं, स्वाद का विषय है जिस पर पहले एसओ पर चर्चा की गई है। मैं कभी-कभी उस मुहावरे का उपयोग करके खुद को पकड़ता हूं, और जब भी मैं करता हूं तब भी मैं बहुत शर्मिंदा नहीं हूं। मैं इसके बारे में कम शौकीन हूं, फिर भी मैं करता था; यह एक पुरानी सी प्रोग्रामर की आदत है। –

0

परंपरा के मुताबिक, आप जैसे करने के लिए सक्षम कर रहे हैं में निर्मित प्रकार यह करते हैं, स्वत: जनरेट असाइनमेंट ऑपरेटरों यह करना है, यह आप ऐसा कर सकते हैं: श्रृंखलित काम की इजाजत दी -

int x, y, z; 
x = y = z = 0; 

if ((x = 1) != 0) { ... } 

के लिए अपने वर्ग की घटनाओं के लिए इन अर्थ विज्ञान रखने के लिए, आप *this लौटना ही होगा। अगर तुम सिर्फ this आप अपने उदाहरण के सूचक के लौटने होगी वापसी, और श्रृंखलित काम से काम नहीं होगा - वहाँ String * के लिए कोई operator=, वहाँ पहले से ही अपने सटीक सवाल का जवाब String

8

@larsmans के लिए एक है, इसलिए मैं वास्तव में digress होगा: यह कुछ बकवास कोड है!

यहां मुद्दा यह 3 गुना है:

  1. तुम बस प्रतिलिपि निर्माता (कुछ)
  2. strcpy बेहतर strncpy द्वारा प्रतिस्थापित किया जा सकता है, जो कुछ बाध्य जाँच
  3. करता है के कोड दोहराया यह अपवाद सुरक्षित नहीं है

1) और 2) अधिक स्टाइलि हैं किसी भी चीज से चिपक गया, लेकिन 3) एक बड़ी चिंता है

संपादित करें: जैसा कि @ जेरी कॉफिन द्वारा इंगित किया गया है, यह स्वयं-असाइनमेंट के खिलाफ सुरक्षित नहीं है। ऐसा है कि sobj और _string वर्णों की एक ही सरणी पर इंगित करें, तो आप बड़ी परेशानी में हैं। इस पोस्ट के अंत में आसान समाधान भी इस स्थिति को शामिल करता है।

नहीं अपवाद सुरक्षित

के कोड, अर्थात् के एक हिस्से पर एक नजर है, else हिस्सा:

_size = strlen(sobj); 
    delete[] _string; 
    _string = new char[ _size + 1 ]; 
    strcpy(_string, sobj); 

अगर, किसी कारण से, new फेंकता है तो क्या होगा?

  • _size वर्ष सूचक ... जो

मुक्त कर दिया कर दिया गया है इसलिए केवल वस्तु के अनुपयोगी राज्य के (छमाही में छोड़ दिया है नहीं करने के लिए नए स्ट्रिंग के मूल्य

  • _string अंक हैं नई वस्तु से अपने डेटा, वर्ष से आधा), लेकिन यह भी नष्ट नहीं किया जा सकता है (जब तक नाशक लीक ...?)

    जोड़ना अपवाद सुरक्षा, मुश्किल तरीके से

    _size = strlen(sobj); 
        delete[] _string; 
    
        try { 
        _string = new char[ _size + 1 ]; 
        } catch(...) { 
        _size = 0; _string = 0; 
        throw; 
        } 
        strcpy(_string, sobj); 
    

    ठीक है, यह वास्तव में नीचे-लाइन है, लेकिन यह हमें बेसिक अपवाद गारंटी लाता है: कोई कार्यात्मक गारंटी है, लेकिन एक गारंटी नहीं है कि कोड तकनीकी रूप से सही है (कोई दुर्घटना, कोई रिसाव)।

    अपवाद सुरक्षा, आसान तरीका जोड़ना: कॉपी और स्वैप मुहावरा

    में अधिक पूर्ण विवरण प्राप्त करें: What is the copy-and-swap idiom ?

    void swap(String& lhs, String& rhs) { 
        using std::swap; 
        swap(lhs._size, rhs._size); 
        swap(lhs._string, rhs._string); 
    } 
    
    String& String::operator=(String other) { // pass-by-value 
        swap(*this, other); 
        return *this; 
    } 
    

    यह कैसे काम करता है?

    • हम वास्तविक प्रतिलिपि
    • हम आदान प्रदान मूल्यों के लिए स्वैप समारोह का पुन: उपयोग के लिए प्रति निर्माता का पुन: उपयोग
    • हम सफाई

    के लिए नाशक का पुन: उपयोग और यह से भी बेहतर है पिछले संस्करण भी, अब हमारे पास मजबूत अपवाद गारंटी है: यह लेन-देन है, इस प्रकार यदि यह विफल हो जाता है, तो हम जिस स्ट्रिंग को सौंपा गया है वह अपरिवर्तित है (जैसा कि कुछ नहीं हुआ था)।

    More about Exception Guarantees

    मैं थोड़ा daunted कि एक सी ++ ट्यूटोरियल इस तरह के संदिग्ध कोड को बढ़ावा देने के हैं हूँ, प्रार्थना मुझे बताओ यह क्या नहीं करना है, इसका एक उदाहरण:/

  • +0

    @ जेरी: अच्छा बिंदु, मैं इसे संपादित कर दूंगा। –

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