2017-09-08 31 views
29

मुझे यकीन है कि const vector<int *> के सही अर्थ तो मैं एक विचार प्राप्त करने के लिए नीचे दिए गए कोड संकलित लेकिन अब अधिक उलझन में हूँ नहीं हूँ।इंट पॉइंटर्स के कॉन्स्ट वेक्टर में डीरेन्स्क्रिप्टेड तत्व क्यों परिवर्तनीय है?

vector<int *> v; 
int x = 1, y = 2; 
v.push_back(&x); 
v.push_back(&y); 

const vector<int *> w = v; 
w[0] = &y; //failed. Element is a constant pointer? 
*(w[0]) ++; //failed. Element pointer references to constant value? 

अगर मैं यहाँ बंद कर दिया था, मैं मान लिया होता है कि const vector<int *>const int * const का एक वेक्टर है, लेकिन फिर मैं निम्नलिखित जो स्पष्ट रूप से है कि इस धारणा का खण्डन करने की कोशिश की।

*(w[0]) += 3; //passed. Value not constant? 
*(w[0]) = 20; //passed. Why... 

अब *(w[0]) कारण मेरे लिए अज्ञात के लिए स्पष्ट रूप से ++ और += और काम अलग ढंग से व्यवहार करता है। मैंने खुद को आश्वस्त किया कि const vector केवल vector वर्ग की निरंतर वस्तु घोषित करता है और उपरोक्त परिणाम vector कक्षा के ऑपरेटर ओवरलोडिंग के वास्तविक कार्यान्वयन पर निर्भर हो सकते हैं। लेकिन मैं इसके चारों ओर अपने सिर लपेट नहीं सकता। क्या कोई समझाने में मदद कर सकता है, कृपया?

यदि यह प्रासंगिक है, तो मैक पर g ++ 4.2 का उपयोग करता हूं।

+1

आपको यह दिलचस्प मिल सकता है: पोस्ट को पूर्व-वृद्धि में बदलें और देखें कि दूसरी विफलता उदाहरण पर क्या होता है। '++ * (डब्ल्यू [0]);'। – WhozCraig

+1

मुझे लगता है कि भ्रम का एक बड़ा स्रोत '* (डब्ल्यू [0]) ++;' '(* w [0]) ++ के बजाय लिख रहा है, '(जो मुझे लगता है कि इच्छित परिणाम संभवतः था)। ऑपरेटर प्राथमिकता कभी-कभी थोड़ा मुश्किल हो सकती है। – Kat

उत्तर

33

इंट पॉइंटर्स के कॉन्स्ट वेक्टर में डीरेन्स्क्रिप्टेड तत्व क्यों परिवर्तनीय है?

const vector<int *> के लिए, तत्व, const गैर करने के लिए const सूचक है, यानी int * const होगा ताकि आप वस्तु सूचक द्वारा बताया संशोधित कर सकते हैं, लेकिन सूचक नहीं ही।

Operator Precedence के अनुसार, पोस्टफ़िक्स वेतन वृद्धि ऑपरेटर operator* की तुलना में अधिक पूर्वता है, तो *(w[0]) ++;

* ((w[0]) ++); 

सूचक पर वेतन वृद्धि पहली बार में किया जाता है के बराबर है, तो यह विफल रहता है। w[0] = &y; पॉइंटर को संशोधित करने का भी प्रयास कर रहा है, इसलिए यह भी विफल रहता है।

दूसरी ओर, (*w[0]) ++; (यानी पॉइंट पर वृद्धि) ठीक होगा। और निम्नलिखित कथन भी ठीक हैं, क्योंकि वे पॉइंटर द्वारा इंगित वस्तुओं को संशोधित कर रहे हैं, पॉइंटर्स नहीं।

*(w[0]) += 3; //passed. 
*(w[0]) = 20; //passed. 
9

यह operator precedence का मामला है।

जब आप *(w[0]) ++ करते हैं तो आप पॉइंटर को संशोधित करने का प्रयास करते हैं।

जब आप *(w[0]) += 3 करते हैं तो आप पॉइंटर द्वारा इंगित डेटा को संशोधित करते हैं।

5

w एक const vector<int *> है। constक्वालीफायर वेक्टर लिए आवेदन किया है। इसलिए, इसी const सदस्य समारोह operator[] के लिए उपयोग किया जाएगा:

const_reference operator[](size_type pos) const;

के बाद से वेक्टर const -qualified है और प्रकार int * (और नहीं const int *) के तत्व शामिल हैं, अभिव्यक्ति w[0] के प्रकार int * const& है (const int *& के बजाय)।constness सूचक ही है, डेटा के लिए नहीं बताया जा रहा लागू किया जाता है: यह है कि यह एक एक निरंतर सूचक को एक निरंतर int के लिए एक int और नहीं एक सूचक के लिए एक संदर्भ के संदर्भ में है, है।

कर *(w[0]) += 3 आप सूचक की मूल्य वेक्टर रिटर्न (जो const है) को संशोधित नहीं कर रहे हैं, लेकिन मूल्य इस सूचक की ओर इशारा करते है। चूंकि यह सूचक int * const (और const int *) प्रकार का नहीं है, इसलिए आप जो भी इंगित कर रहे हैं उसे संशोधित कर सकते हैं, इसलिए यह काम करता है। हालांकि, w[0] = &y निरंतर सूचक पर असाइनमेंट कर रहा है, इसलिए यह संकलित नहीं होता है।

0

const vector<T> आप T const & (अर्थातconst T &) के रूप में उसके तत्वों तक पहुंचने देता है। इस मामले में, Tint * है, इसलिए यह int * const & है, जो एक सूचक का संदर्भ है जो int पर इंगित करता है। सूचक स्थिर है, लेकिन int नहीं है।

वेक्टर के प्रकार (अर्थातvector<const int*>) जिस स्थिति में तत्वों int const * const & द्वारा ही पहुंचा जा होगा vector<int const *> होने की जरूरत है।

नीचे की रेखा, स्थिरता टेम्पलेट्स के साथ संक्रमणीय है लेकिन पॉइंटर्स के साथ नहीं है। और यदि आप टेम्पलेट्स में पॉइंटर्स डालते हैं, तो आप दोनों व्यवहारों का थोड़ा सा हिस्सा प्राप्त करते हैं।

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