2009-03-23 22 views
15

एक परियोजना मैं बनाए रखने में, मैं साधारण get/set तरीकोंआदिम प्रकारों को पारित करने के संदर्भ का क्या उपयोग है?

const int & MyClass::getFoo() { return m_foo; } 

void MyClass::setFoo(const int & foo) { m_foo = foo; } 

कर रही बजाय निम्नलिखित में बात क्या है के लिए इस तरह कोड का एक बहुत कुछ देखा है?

int MyClass::getFoo() { return m_foo; } // Removed 'const' and '&' 

void MyClass::setFoo(const int foo) { m_foo = foo; } // Removed '&' 

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

उत्तर

20

अंतर यह है कि यदि आप उस परिणाम को अपने संदर्भ में प्राप्त करते हैं तो आप फ़ंक्शन को याद किए बिना अपने स्वयं के चर नाम में पूर्णांक सदस्य चर के परिवर्तनों को ट्रैक कर सकते हैं।

const &int x = myObject.getFoo(); 
cout<<x<<endl; 
//... 
cout<<x<<endl;//x might have changed 

यह शायद सबसे अच्छा डिजाइन पसंद नहीं है, और यह एक चर दायरे से मुक्त कर दिया जाता है कि लौटा दिया जाता है मामले में, एक संदर्भ (स्थिरांक या नहीं) वापस जाने के लिए बहुत खतरनाक है। इसलिए यदि आप कोई संदर्भ वापस लेते हैं, तो यह सुनिश्चित करने के लिए सावधान रहें कि यह एक चर नहीं है जो दायरे से बाहर हो जाता है।

संशोधक के लिए थोड़ा सा अंतर भी है, लेकिन फिर शायद ऐसा कुछ नहीं है जो करने योग्य है या जिसका उद्देश्य था।

void test1(int x) 
{ 
    cout<<x<<endl;//prints 1 
} 

void test2(const int &x) 
{ 
    cout<<x<<endl;//prints 1 or something else possibly, another thread could have changed x 
} 

int main(int argc, char**argv) 
{ 
    int x = 1; 
    test1(x); 
    //... 
    test2(x); 
    return 0; 
} 

तो अंतिम परिणाम यह है कि पैरामीटर पारित होने के बाद भी आप परिवर्तन प्राप्त करते हैं।

+0

"संदर्भ (कॉन्स या नहीं) वापस करना बहुत खतरनाक है" - मैं उत्सुक हूं, फिर आप अधिक हेवीवेट मूल्य कैसे वापस करते हैं? हो सकता है कि खराब डिजाइन का संकेत हो, लेकिन मैं कॉन्स रेफरी द्वारा स्ट्रिंग्स लौटता हूं। –

+0

@me - मैं यह नहीं कह रहा हूं कि स्ट्रिंग हेवीवेट हैं, मैं बस उन्हें कॉपी करने के लिए (स्वीकार्य रूप से शायद मामूली) ओवरहेड से बचना पसंद करता हूं। –

+0

इस तरह आपको ऑब्जेक्ट जीवनकाल के बारे में सोचना होगा। यह जटिल डेटाटाइप के लिए लायक हो सकता है, लेकिन प्राइमेटिव्स के लिए जो संदर्भों के समान लागत पर प्रतिलिपि बनाई गई हैं। – sharptooth

5

एक मूल्य लौटने और एक कॉन्स्ट संदर्भ लौटने के बीच मुख्य अंतर यह है कि आप उस संदर्भ को const_cast कर सकते हैं और मान को बदल सकते हैं।

यह खराब डिजाइन का एक उदाहरण है और एक स्मार्ट डिज़ाइन बनाने का प्रयास जहां आसान और संक्षिप्त डिजाइन पर्याप्त से अधिक होगा। केवल एक मूल्य लौटने के बजाय लेखक कोड के पाठकों को लगता है कि वह क्या इरादा रख सकता था।

2

मुझे लगता है कि इस प्रकार का कोड लिखा गया है, जिन्होंने संदर्भों की अवधारणा को गलत समझा है और इसे मूलभूत डेटा प्रकारों सहित सब कुछ के लिए उपयोग किया है। मैंने इस तरह के कुछ कोड भी देखे हैं और ऐसा करने का कोई फायदा नहीं देख सकते हैं।

0

छोड़कर

void MyClass::setFoo(const int foo) 
void MyClass::setFoo(const int& foo) 

कोई मतलब नहीं है और लाभ तो के रूप में आप 'foo' वेरिएबल के अंदर 'setFoo' कार्यान्वयन पुन: उपयोग करने में सक्षम नहीं होगा नहीं है। और मेरा मानना ​​है कि 'int &' सिर्फ इसलिए है क्योंकि लड़का सिर्फ सभी चीजों को कॉन्स्ट संदर्भ द्वारा पारित करने के लिए उपयोग किया जाता है और इसमें कुछ भी गलत नहीं है।

4

बहुत लाभ नहीं है। मैंने इसे ढांचे या मैक्रो उत्पन्न गेटर्स और सेटर्स में पहले देखा है। मैक्रो कोड आदिम और गैर-पीओडी प्रकारों के बीच अंतर नहीं करता था और बस सेटर्स के लिए बोर्ड में const type& का उपयोग करता था। मुझे संदेह है कि यह एक दक्षता मुद्दा या वास्तविक गलतफहमी है; संभावना है कि यह एक स्थिरता मुद्दा है।

+0

+1 इसे एक स्थिरता समस्या कहने के लिए +1। –

7

मेरे लिए, प्राइमेटिव्स के लिए कॉन्स्ट संदर्भ गुजरना एक गलती है।या तो आपको मूल्य को संशोधित करने की आवश्यकता है, और उस स्थिति में आप गैर-कॉन्स्ट संदर्भ पास करते हैं, या आपको केवल मूल्य तक पहुंचने की आवश्यकता है और उस स्थिति में आप const पास करते हैं।

कॉन्स संदर्भ केवल जटिल कक्षाओं के लिए उपयोग किया जाना चाहिए, जब वस्तुओं की प्रतिलिपि बनाना एक प्रदर्शन समस्या हो सकती है। प्राइमेटिव के मामले में, जब तक आपको चर के मान को संशोधित करने की आवश्यकता न हो, आपको संदर्भ पास नहीं करना चाहिए। कारण यह है कि संदर्भगैर संदर्भ की तुलना में अधिक गणना समय लेते हैं, के बाद से संदर्भ साथ, कार्यक्रम एक तालिका में वस्तु का पता खोजने के लिए देखने के लिए की जरूरत है। जब यह लुकअप समय प्रतिलिपि समय से छोटा होता है, तो संदर्भ एक सुधार होते हैं।

आम तौर पर, ints और पतों निम्न स्तर के कार्यान्वयन में एक ही बाइट लंबाई की है। तो int को फ़ंक्शन के लिए रिटर्न वैल्यू के रूप में कॉपी करने का समय पता की प्रतिलिपि बनाने के समय के बराबर है। लेकिन इस मामले में जहां int वापस आ गया है, कोई लुकअप नहीं किया जाता है, इसलिए प्रदर्शन बढ़ जाता है।