2011-12-05 28 views
25

पर रिटर्न संदर्भ मेरे पास कक्षा में सदस्य के रूप में एक वेक्टर है और मैं इसे getVector() फ़ंक्शन के माध्यम से संदर्भ प्रस्तुत करना चाहता हूं, ताकि बाद में इसे संशोधित करने में सक्षम हो सकें। क्या यह कार्य बेहतर नहीं है वेक्टर() को कॉन्स होने के लिए मिलता है? हालांकि मुझे निम्नलिखित कोड में "क्वालिफ़ायर प्रकार के बाध्यकारी संदर्भ में गिरा दिया गया ..." त्रुटि मिली। क्या संशोधित किया जाना चाहिए?वेक्टर सदस्य चर

class VectorHolder 
{ 
public: 
VectorHolder(const std::vector<int>&); 
std::vector<int>& getVector() const; 

private: 
std::vector<int> myVector; 

}; 

std::vector<int> &VectorHolder::getVector() const 
{ 
return myVector; 
} 

उत्तर

27

चूंकि यह const सदस्य फ़ंक्शन है, इसलिए रिटर्न प्रकार गैर-कॉन्स्ट संदर्भ नहीं हो सकता है। इसे const बनाएं:

const std::vector<int> &VectorHolder::getVector() const 
{ 
    return myVector; 
} 

अब ठीक है।

यह ठीक क्यों है? क्योंकि const सदस्य फ़ंक्शन में, प्रत्येक सदस्य const इस तरह से संशोधित नहीं किया जा सकता है, जिसका अर्थ है myVector फ़ंक्शन में const वेक्टर है, इसलिए आपको रिटर्न प्रकार const भी करना है, यह संदर्भ देता है।

अब आप उसी ऑब्जेक्ट को संशोधित नहीं कर सकते हैं। आप क्या करना है और क्या नहीं कर सकते हैं कर सकते हैं क्या देखें:

std::vector<int> & a = x.getVector();  //error - at compile time! 

const std::vector<int> & a = x.getVector(); //ok 
a.push_back(10);       //error - at compile time! 

std::vector<int> a = x.getVector();  //ok 
a.push_back(10);       //ok 

वैसे, मैं सोच रहा हूँ तुम क्यों पहली जगह में इस तरह के VectorHolder की जरूरत है।

+0

इस तरह तो कोड जहां इसे वापस से बाद लौटे वेक्टर संशोधित करने के लिए असंभव है:

इसलिए आप getVector() इस तरह की घोषणा करने के लिए है? – arjacsoh

+0

@arjacsoh: यह निर्भर करता है। संपादन देखें। – Nawaz

13

यह दोनों स्थिरांक और परिवर्तनशील वेरिएंट घोषित करने के लिए है, इसलिए की तरह असामान्य बात नहीं है:

std::vector<int>& VectorHolder::getVector() { 
    return myVector; 
} 
const std::vector<int>& VectorHolder::getVector() const { 
    return myVector; 
} 

अपने कार्यक्रम के साथ मूल समस्या है कि आप एक स्थिरांक विधि से एक गैर स्थिरांक संदर्भ वापसी है।

std::vector<int>& VectorHolder::getVector() const { 
    return myVector; // << error: return mutable reference from const method 
} 

ताकि आप इसे इस प्रपत्र का उपयोग const बनाने:

const std::vector<int>& VectorHolder::getVector() const { 
    return myVector; // << ok 
} 

और जब यह एक गैर स्थिरांक विधि में है या ग्राहक एक गैर स्थिरांक संदर्भ रखती है, तो आप कानूनी तौर पर एक गैर-उपयोग कर सकते हैं स्थिरांक विधि:

std::vector<int>& VectorHolder::getVector() { 
    return myVector; // << ok 
} 

अंत में, आप (कुछ मामलों में) कोई मान सकता है:

std::vector<int> VectorHolder::getVector() const { 
    return myVector; // << ok 
} 

क्योंकि प्रतिलिपि के लिए कोई उत्परिवर्तन की आवश्यकता नहीं है और आंतरिक डेटा का कोई संपर्क नहीं प्रदान करता है।

ताकि आप दोनों प्रकारों को अक्सर घोषित कर सकें।

दोनों की घोषणा के परिणाम हैं:

VectorHolder m; 
const VectorHolder c; 

m.getVector().size(); // << ok 
c.getVector().size(); // << ok - no mutation 

m.getVector().push_back(a); // << ok 
c.getVector().push_back(a); // << error: attempt to mutate const reference because the const vector is returned 

तो यह सब (तरीकों में से अतिरेक से अलग) अच्छी तरह से बाहर काम करता है।

2

फ़ंक्शन getVector को const के रूप में घोषित किया जा सकता है। यह एक संदर्भ देता है जिसे संशोधित किया जा सकता है, इसलिए जब वास्तविक कार्य कक्षा में कुछ भी संशोधित नहीं करता है, तो कॉलर आंतरिक डेटा को संशोधित करने में सक्षम होगा।

यह घोषित रूप में:

std::vector<int>& getVector(); 

आप एक वेक्टर कि बदला नहीं जा सकता, उपयोग दोनों वेक्टर और समारोह पर const संशोधक वापस जाने के लिए एक समारोह चाहते हैं:

const std::vector<int>& getVector() const; 
0

कारण यह है कि एक कॉन्स सदस्य समारोह केवल कॉन्स संदर्भों को वापस करना चाहिए। ऐसा इसलिए है क्योंकि एक कॉन्स फ़ंक्शन में, प्रत्येक डेटा सदस्य स्थिर हो जाता है।

std::vector<int> &VectorHolder::getVector() const; 
+2

उपर्युक्त के बावजूद, शायद, आपके आंतरिक कंटेनर का पर्दाफाश करना अच्छा विचार नहीं है। यदि कुछ दिन आप वेक्टर से मानचित्र पर माइग्रेट करने का निर्णय लेते हैं, तो आपके उपयोगकर्ता प्रभावित होंगे। मैं इसके बजाए इटरेटर को लागू करने का सुझाव दूंगा। – Lev

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