2010-02-28 11 views
8

निम्नलिखित कोड पर विचार करें:विफलता के मामले में एक कॉन्स QString संदर्भ कैसे वापस करें?

const QString& MyClass::getID(int index) const 
{ 
    if (i < myArraySize && myArray[i]) { 
     return myArray[i]->id; // id is a QString 
    } else { 
     return my_global_empty_qstring; // is a global empty QString 
    } 
} 

मैं विधि की वापसी प्रकार बदले बिना एक खाली QString के लिए कैसे बच कर सकते हैं? (ऐसा लगता है कि स्टैक पर आवंटित एक खाली क्यूस्ट्रिंग लौटना एक बुरा विचार है)

धन्यवाद।

+4

हालांकि आम तौर पर कॉन्स संदर्भ वापस करना अच्छा होता है, मुझे लगता है कि यदि आपको आवश्यकता हो तो आप मूल्य के आधार पर क्यूस्ट्रिंग लौटने से दूर हो सकते हैं। यह प्रतिलिपि बनाने के लिए बहुत सस्ता लिखने पर प्रतिलिपि है। –

उत्तर

8

आप नहीं कर सकते। या तो एक स्थिरांक संदर्भ वापसी नहीं है या इस तरह एक स्थानीय स्थिर चर का उपयोग:

const QString& MyClass::getID(int index) const { 
    static const QString emptyString; 

    if (i < myArraySize && (myArray[i] != 0)) { 
     return myArray[i]->id; // id is a QString 
    } else { 
     return emptyString; 
    } 
} 

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

वैसे, क्या आप वास्तव में अपनी कक्षा में सी शैली शैली का उपयोग कर रहे हैं?

+0

नहीं, मैं नहीं हूं, यह एकता के लिए था। – moala

3

चूंकि यह const मान वापस करने की उम्मीद है, इसलिए मुझे एक वैश्विक स्ट्रिंग को वापस करने के लिए ऐसे सभी कार्यों द्वारा उपयोग किए जाने वाले वैश्विक (या स्थिर कॉन्स) खाली QString होने में कोई समस्या नहीं है।

हालांकि मैं नाम के बारे में जंगली नहीं हूं। मैं उम्मीद करता हूं कि "खाली" क्यूस्ट्रिंग क्यूस्ट्रिंग कक्षा का एक स्थिर आधार सदस्य होगा। तो आपका कोड इसके बजाए ऐसा दिखाई देगा।

const QString& MyClass::getID(int index) const 
{ 
    if (i < myArraySize && myArray[i]) { 
     return myArray[i]->id; // id is a QString 
    } else { 
     return QString::EmptyString; // is a global empty QString 
    } 
} 
+0

वास्तव में, यह बिंदु था, क्या यह आंतरिक रूप से क्यूटी के लिए मौजूद है (मुझे यह नहीं मिला), या क्या यह इस स्थिर खाली QString के बिना ऐसा करने का एक और तरीका है? – moala

+2

मुझे यकीन है कि अन्य तरीके मौजूद हैं। लेकिन इस समस्या को हल करने के लिए एक स्थिर खाली QString एक _good_ तरीका है। आपको इससे बचने की कोशिश नहीं करनी चाहिए। –

0

कैसे एक पूर्व प्रारंभ डिफ़ॉल्ट मान का उपयोग कर के बारे में:

const QString& MyClass::getID(int index, const QString& def = QString()) const 
{ 
    if (i < myArraySize && myArray[index]) { 
     return myArray[index]->id; // id is a QString 
    } else { 
     return def; 
    } 
} 
+1

क्या यह निम्न समस्या का समाधान नहीं करता है? http://stackoverflow.com/questions/667396/parameter-passed-by-const-reference-returned-by-const-reference – moala

+0

यह इस बात पर निर्भर करता है कि आप इसका उपयोग कैसे करते हैं, अगर आप इस फ़ंक्शन कॉल को 'कॉन्स्ट क्यूस्ट्रिंग' यह खतरनाक है, लेकिन यदि आप इसे 'क्यूस्ट्रिंग' को असाइन करते हैं तो यह नहीं करता है। यह मेरे उदाहरण में ठीक काम करता है। –

+0

फिर, कॉलर बिंदु पर, डिफ़ॉल्ट वापसी मान का उपयोग करते समय, यह कंस QString और theId = getId (i, QString()) बन जाता है; लेकिन अस्थायी QString नष्ट हो जाएगा, तो संदर्भ टूटा हुआ है, है ना? – moala

0

यदि आप एक संदर्भ लौटने पर जोर देते हैं, आप एक वस्तु का उल्लेख करने होनी चाहिए; तो आपके पास अपने उदाहरण में कहीं भी क्यूस्ट्रिंग ऑब्जेक्ट होना चाहिए, इसके आसपास कोई रास्ता नहीं है।

हालांकि एक तकनीक अपने मामले के लिए उपयुक्त लगता है कि आपके प्रक्रिया में परिवर्तन करना एक डिफ़ॉल्ट आईडी को स्वीकार करने के मामले में वापस जाने के लिए अनुक्रमणिका सीमा से बाहर है:

const QString& MyClass::getID(int i, const QString& default) const 
{ 
    if(i < myArraySize && myArray[i]) 
    return myArray[i]->id; 
    else 
    return default; 
} 

तुम भी सूचकांक अगर एक अपवाद फेंक सकता है सीमा से बाहर है, तो आपको असफलता पर वास्तव में वापस आने की आवश्यकता नहीं होगी, लेकिन शायद यह नहीं है कि आप क्या चाहते हैं।

+3

डिफ़ॉल्ट एक बुरा विचार है क्योंकि यह एक सी ++ कीवर्ड –

+1

है, भले ही यह आकर्षक लग रहा हो, http://stackoverflow.com/questions/667396/parameter-passed-by-const-reference-returned-by-const-reference से पता चलता है कि यह खराब हो सकता है ... – moala

2

आप वापसी प्रकार को बदले बिना इससे बच नहीं सकते हैं।

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

यही कारण है कि सी ++ एपीआई डिज़ाइन मार्गदर्शिकाएं जो बाइनरी संगतता समस्याओं से अवगत हैं, सावधानीपूर्वक विचार किए बिना const& वापस नहीं करने की सलाह देते हैं।

0

क्यूस्ट्रिंग :: शून्य पर्याप्त होगा?

+0

क्यूटी 4.6.2 किसी कारण से 'QString' के ऐसे स्थिर सदस्य को याद कर रहा है। लेकिन 'क्यूस्ट्रिंग :: क्यूस्ट्रिंग()' नल स्ट्रिंग "बनाता है और मुझे लगता है कि कन्स्ट्रक्टर 'क्यूस्ट्रिंग :: प्राइवेटडाटा * निजी = क्यूस्ट्रिंग :: कुछ स्टेटिक नलडाटा' – ony

+1

क्यूस्ट्रिंग :: क्यूटी 4.6 के मेरे उदाहरण में मौजूद है। 2 (और, मुझे उम्मीद है, तुम्हारा भी)। यह अवमूल्य है, लेकिन अभी भी वहाँ है। यदि आप ईएलएफ, मैक-ओ, या पीई (लिनक्स, * बीएसडी, मैकोज़, विंडोज) फ़ाइलों का उपयोग करने वाले प्लेटफॉर्म का उपयोग कर रहे हैं तो आपको क्यूस्ट्रिंग :: नल का उपयोग करने में सक्षम होना चाहिए। एम्बेडेड प्लेटफार्मों में शायद अधिक प्रतिबंध हैं। http://lists.trolltech.com/qt-interest/2005-11/msg01002.html – blarf

0

आप getId() कामों को बदले बिना खाली क्यूस्ट्रिंग की आवश्यकता से बच नहीं सकते हैं। लेकिन वसंत के लिए दो दृष्टिकोण हैं:

  • चुपचाप एक खाली स्ट्रिंग लौटने के बजाय, अपवाद फेंक दें; या
  • किसी संदर्भ को वापस करने के बारे में परेशान न करें, और ऑब्जेक्ट की प्रतिलिपि बनाने की लागत को समाप्त करने के लिए return value optimization पर भरोसा करते हुए केवल एक क्यूस्ट्रिंग लौटें।