2012-02-29 29 views
17

मैंने यह देखने का निर्णय लिया कि किसी सदस्य को संदर्भ निर्दिष्ट करने से सदस्य को संदर्भ मिलेगा। मैंने परीक्षण करने के लिए निम्नलिखित स्निपेट लिखा था। एक सदस्य वर्ग के रूप में std::string के साथ एक साधारण वर्ग Wrapper है। मैं निर्माता में const string& लेता हूं और इसे सार्वजनिक सदस्य चर के लिए असाइन करता हूं। बाद में main() विधि में मैं सदस्य चर को संशोधित करता हूं लेकिन string मैं कन्स्ट्रक्टर को पास कर देता हूं अपरिवर्तित रहता है, कैसे आते हैं? मुझे लगता है कि जावा में चर बदल गया होगा, क्यों नहीं इस कोड स्निपेट में? संदर्भ इस मामले में वास्तव में कैसे काम करते हैं?किसी निर्माता के संदर्भ में पासिंग

#include <iostream> 
#include <string> 
using namespace std; 

class Wrapper 
{ 
public: 
    string str; 

    Wrapper(const string& newStr) 
    { 
     str = newStr; 
    } 
}; 

int main (int argc, char * const argv[]) 
{ 
    string str = "hello"; 
    cout << str << endl; 
    Wrapper wrapper(str); 
    wrapper.str[0] = 'j'; // should change 'hello' to 'jello' 
    cout << str << endl; 
} 
+2

सी ++ में प्रकार आप जो डिक्री करते हैं, और वे जादूगर रूप से कुछ और नहीं बनते हैं। आप 'स्ट्रिंग' कहते हैं, और आपको 'स्ट्रिंग' मिलता है। यदि आप एक संदर्भ चाहते थे, तो आप 'स्ट्रिंग' कहेंगे। –

+0

आपने बहुत सरल प्रश्न वाले लोगों से दुर्व्यवहार किया :) – Mikhail

+2

जावा में वेरिएबल नहीं बदला होगा क्योंकि कोड संकलित नहीं होगा; जावा में तारों को संशोधित करने की अनुमति नहीं है। –

उत्तर

22

एक निर्माता में एक संदर्भ असाइन करने के लिए आप एक संदर्भ सदस्य

class A{ 
    std::string& str; 
public: 
    A(std::string& str_) 
    : str(str_) {} 
}; 

str अब मूल्य आपके द्वारा व्यतीत लिए एक संदर्भ है की आवश्यकता है। एक ही स्थिरांक refs

class A{ 
    const std::string& str; 
public: 
    A(const std::string& str_) 
    : str(str_) {} 
}; 

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

5

क्योंकि Wrapper::str, एक संदर्भ नहीं है, यह एक स्वतंत्र वस्तु है। तो जब आप str = newStr करते हैं, तो आप स्ट्रिंग स्ट्रिंग कर रहे हैं।

1

आपको Wrapper::str को string& के रूप में घोषित करना चाहिए, string के रूप में नहीं।

3

आप के रूप में एक संदर्भ के रूप में एक प्रारंभकर्ता का उपयोग करें और str घोषित करने के लिए की जरूरत है:

class Wrapper { 
public: 
    string &str; 

    Wrapper(string& newStr) 
     : str(newStr) { 
    } 
}; 

जिस तरह से आप यह लिख रहे हैं, तुम सब क्या कर रहे हैं आप constuctor के पास संदर्भ के मान को कॉपी कर रहा है । आप संदर्भ को सहेज नहीं रहे हैं। एक वर्ग सदस्य के रूप में संदर्भ घोषित करके और इसे किसी अन्य स्ट्रिंग उदाहरण के संदर्भ में प्रारंभ करके, आपको वह व्यवहार मिलेगा जिसे आप ढूंढ रहे हैं।

+1

आपका कोड संदर्भ-टू-कॉन्स्ट के साथ संदर्भ-से-म्यूटेबल को प्रारंभ करने का प्रयास करता है। –

+0

फिक्स्ड ... ओपी से अंधेरे से कॉपी करने के लिए मुझे यही मिलता है। – andand

5
class Wrapper 
{ 
public: 
    string& str; 

    Wrapper(string& newStr) : str(newStr) {} 
}; 

ध्यान दें, यदि आप एक const string& स्वीकार नहीं कर सकते हैं और यह एक string& में स्टोर, आप ऐसा करने में स्थिरांक-शुद्धता खो देगा।

1

आपका मुख्य शरीर चर std::string है।

आपका पैरामीटर चर const std::string& है।

संदर्भ में स्थिरांक हमेशा "निम्न स्तर का आधार" होता है, जिसका अर्थ है कि यह वस्तु के प्रकार को वास्तविक वस्तु को संशोधित नहीं करता है।

इसके विपरीत "शीर्ष स्तर का आधार" एक वास्तविक वस्तु को संशोधित करता है। स्पष्टीकरण के लिए C++ Primer on Top level const पढ़ें।

यहां अपने काम की तरह है जब आप तर्क पारित लग रहा है:

const std::string& = std::str; //Values are ommited 
// i.e const std::string newStr = std::string str 

आप एक non-const value जो स्वीकार्य है के साथ एक const type reference आरंभ कर रहे हैं। आपको उस संदर्भ का उपयोग करके std::string str के मान को परिवर्तित नहीं करना चाहिए।और, यदि आप कन्स्ट्रक्टर के अंदर newStr के मान को बदलने का प्रयास करते हैं, तो आप संकलन त्रुटि प्राप्त करेंगे।

इसके बाद आप निर्माता जो भी स्वीकार्य है अंदर एक और काम कर रहे हैं:

std::string = const std::string 

तथ्य यह है कि wrap.str[0]strmain का परिवर्तन नहीं किया है कि, हालांकि एक संदर्भ class str, class str का दृष्टांत इस्तेमाल किया गया था इसकी अपनी वस्तु है और main str से जुड़ा नहीं है। पैरामीटर में उस संदर्भ का उपयोग करना उस पैरामीटर को main str पर लिंक करता है; main str से class str पर नहीं।

यदि आपकी कक्षा चर का संदर्भ दिया गया था, तो यह बदल सकता था।

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