2010-04-02 15 views
10

क्या यह किसी फ़ंक्शन से किसी ऑब्जेक्ट को वापस करने का सही तरीका है?फ़ंक्शन से स्थानीय ऑब्जेक्ट लौटाना

Car getCar(string model, int year) { 
    Car c(model, year); 
    return c; 
} 

void displayCar(Car &car) { 
    cout << car.getModel() << ", " << car.getYear() << endl; 
} 

displayCar(getCar("Honda", 1999)); 

मुझे "अस्थायी पता लेना" त्रुटि हो रही है। क्या मुझे इस तरह का उपयोग करना चाहिए:

Car &getCar(string model, int year) { 
    Car c(model, year); 
    return c; 
} 

उत्तर

23

getCar रिटर्न मूल्य है, जो सही है द्वारा एक Car

आप उस वापसी मूल्य को पार नहीं कर सकते हैं, जो एक अस्थायी वस्तु है, displayCar में, क्योंकि displayCarCar& लेता है। आप गैर-कॉन्स्ट संदर्भ के लिए एक अस्थायी बाध्य नहीं कर सकते हैं। आप displayCar बदलना चाहिए एक स्थिरांक संदर्भ लेने के लिए:

void displayCar(const Car& car) { } 

या, आप एक स्थानीय चर में अस्थायी स्टोर कर सकते हैं:

Car c = getCar("Honda", 1999); 
displayCar(c); 

लेकिन, यह displayCar एक स्थिरांक संदर्भ लेने के लिए के बाद से यह नहीं करता है बेहतर है ऑब्जेक्ट को संशोधित नहीं करें।

स्थानीय Car चर के संदर्भ को वापस न करें।

+0

आप कॉपी कन्स्ट्रक्टर का आविष्कार किए बिना अस्थायी स्टोर भी कर सकते हैं (जो 'कार सी = गेटकार (...)' में होता है, जो कि कॉन्स्ट के संदर्भ का उपयोग करके होता है: 'कॉन्स कार और सी = गेटकार (...)', यदि आप डॉन करते हैं बाद में 'सी' के माध्यम से परिवर्तन करने की आवश्यकता नहीं है। –

4

किसी फ़ंक्शन से स्थानीय चर के संदर्भ को वापस सुरक्षित करना सुरक्षित नहीं है।

तो हाँ यह सही है:

Car getCar(string model, int year) { 
    Car c(model, year); 
    return c; 
} 
+0

हम्म, मुझे फ़ैक्टरी फ़ंक्शन की तरह कुछ चाहिए जो एक ऑब्जेक्ट बनाएगा और उसे वापस कर देगा। – pocoa

+1

कई (अधिकांश?) कंपाइलर्स 'रिटर्न कार (मॉडल, वर्ष)' को अनुकूलित करते हैं ताकि कोई अतिरिक्त प्रतिलिपि बनाने की आवश्यकता न हो, इसलिए मैं स्पष्ट स्थानीय चर से छुटकारा पाउंगा। –

+0

@ स्टेवेन: कई (अधिकांश?) कंपाइलर्स नामित रिटर्न वैल्यू ऑप्टिमाइज़ेशन (एनआरवीओ) को लागू करते हैं, इसलिए आमतौर पर कोई अंतर नहीं होता है। –

8

आपका समस्या है:

void displayCar(Car &car) { 
    cout << car.getModel() << ", " << car.getYear() << endl; 
} 

आप एक स्थिरांक संदर्भ का उपयोग करना चाहिए:

void displayCar(const Car & car) { 
    cout << car.getModel() << ", " << car.getYear() << endl; 
} 

यह समारोह:

Car getCar(string model, int year) { 
    Car c(model, year); 
    return c; 
} 

ठीक के रूप में यह खड़ा है, लेकिन सभी यह क्या कर रहा है कन्स्ट्रक्टर क्या करता है, इसलिए यह अनावश्यक है।

Car getCar(const string & model, int year) { 

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

0

और भी बेहतर:

Car getCar(string model, int year) { 
     return Car(model, year); 
} 
+0

मेरे जवाब में "प्रतिलिपि संचालन" से मेरा क्या मतलब है। हालांकि वर्तमान में यह मानक समाधान है, यह केवल एक पते लौटने की तुलना में एक महंगा ऑपरेशन है। – themoondothshine

+1

@themoondothshine : अधिकांश कंपाइलर्स (मुझे पता है) यहां आरवीओ प्रदर्शन करेंगे, इसलिए यह वास्तव में एक सस्ता ऑपरेशन है। –

2

हाँ, यह निश्चित रूप से सुरक्षित नहीं एक अस्थायी ऑब्जेक्ट के संदर्भ या एक सूचक वापस जाने के लिए है। जब यह समाप्त हो जाता है (यानी, जब फ़ंक्शन getCar बाहर निकलता है), तो आप "लटकते सूचक" के रूप में जाने जाने वाले तकनीकी के साथ छोड़ देंगे।

हालांकि, यदि आप किसी ऑब्जेक्ट पर कॉपी ऑपरेशंस को कम करने के इच्छुक हैं, तो आपको सी ++ 0x की "मूवमेंट्स ले जाएं" देखना चाहिए। यह एक अपेक्षाकृत नई अवधारणा है, लेकिन मुझे यकीन है कि यह जल्द ही मुख्य धारा बन जाएगा। जीसीसी 4.4 ऊपर सी ++ 0x का समर्थन करता है (सक्षम करने के लिए कंपाइलर विकल्प -std=c++0x का उपयोग करें)।

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