2011-10-17 11 views
5

मान लीजिए कि मेरे पास एक ऐसा फ़ंक्शन है जो एक महत्वपूर्ण परिणाम और कई महत्वपूर्ण परिणाम देता है। मैं इसे घोषित ताकि महत्वहीन परिणाम संदर्भ द्वारा दिया जाता है:फ़ंक्शन से रिटर्न-बाय-रेफरेंस परिणाम को अनदेखा करना

int CalculateStuff(int param1, int param2, int& result1, int& result2); 

मैं कुछ सामान की गणना करने के लिए इस समारोह कॉल करना चाहते हैं, लेकिन कॉल स्थल पर मैं महत्वहीन परिणाम अनदेखा करना चाहते। मैं यह कर सकता है इस प्रकार है:

... 
int dummy1, dummy2; 
int result = CalculateStuff(100, 42, dummy1, dummy2); 
... // do something with the result 

मैं एक और तरीका डमी चर घोषित करने के बिना भी ऐसा ही करने पर विचार करना चाहते हैं:

int result = CalculateStuff(100, 42, *new int, *new int); 

यह एक स्मृति रिसाव (अस्वीकार्य) है, लेकिन एक फायदा है "डमी" नामों से अधिक स्पष्ट रूप से मेरा इरादा दिखा रहा है (परिणामों को अनदेखा कर रहा है)।

तो, क्या होगा अगर मैं यह लिखा था इस प्रकार है:

int result = CalculateStuff(100, 42, auto_ptr(new int).get(), auto_ptr(new int).get()); 

यह कानूनी है? फ़ंक्शन का कोड निष्पादित होने पर अस्थायी पूर्णांक अभी भी मौजूद होंगे? क्या मुझे auto_ptr के बजाय unique_ptr का उपयोग करना चाहिए?

(कृपया मेरे कोड पुनर्रचना का सुझाव नहीं, मैं शायद होगा - लेकिन पहले मैं समझने के लिए कि यह कैसे काम करता है सामान चाहते हैं)

+1

एक टिप्पणी के रूप में जोड़ा गया है क्योंकि यह वास्तव में आपके प्रश्न का उत्तर नहीं देता है - लेकिन मैं आमतौर पर एक अस्थायी नाम घोषित करता हूं और यदि यह आता है तो पास करें। "गणना करें (100, 42, _, _); उचित रूप से स्पष्ट लगता है। – jcoder

उत्तर

4

यह कानूनी है, auto_ptr ऑब्जेक्ट्स अभिव्यक्ति के अंत तक जीवित रहेगा (यानी फ़ंक्शन कॉल)। लेकिन यह नरक के रूप में बदसूरत है।

बस अपने समारोह को ओवरलोड:

int CalculateStuff(int param1, int param2, int& result1, int& result2); 
int CalculateStuff(int param1, int param2) { 
    int r1=0, r2=0; 
    return CalculateStuff(param1, param2, r1, r2); 
} 
+1

वह अभी भी * वही * प्रश्न पूछता है, आप दूसरे अधिभार को कैसे कार्यान्वित करने जा रहे हैं? क्या आप डमी चर का उपयोग करने जा रहे हैं, या' * नया int ' या 'auto_ptr', या क्या, ताकि आप दूसरे से पहले ओवरलोड को कॉल कर सकें? – Nawaz

+0

@ नवाज़ उदाहरण के लिए, दो अस्थायी चर बनाकर, या कुछ तीसरे कार्यान्वयन को कॉल करके (उदाहरण के लिए पॉइंटर्स के साथ एक जिसे आप सुझाव देते हैं) – hamstergene

+0

लेकिन यह वास्तव में सवाल है। – Nawaz

3

एक तरीका अपनाने का सुझाव आप समारोह पर नियंत्रण होगा अगर: वापसी एक std::tuple (या boost::tuple) सभी परिणामों के साथ या एक अधिभार कि अतिरिक्त जरूरत नहीं है लिखना चर।

3

यहां मेरी सलाह है: यदि आपको कोड और उसके अर्थशास्त्र की शुद्धता को समझने के लिए SO पर पूछना है, तो कोड स्पष्ट रूप से आपके इरादे को व्यक्त करने में विफल रहता है।

मुझे लगता है कि पहला संस्करण (dummy1 और dummy2 के साथ) सबसे पारदर्शी है, और यह स्पष्ट रूप से सही है।

आप पाते हैं अपने आप को बार-बार फ़ंक्शन को कॉल और वैकल्पिक परिणाम नहीं चाहते हैं, तो आप एक अधिभार प्रदान कर सकता है:

int CalculateStuff(int param1, int param2, int& result1, int& result2) {} 

int CalculateStuff(int param1, int param2) { 
    int unwanted1, unwanted2; 
    return CalculateStuff(param1, param2, unwanted1, unwanted2); 
} 
4

Bjarne Stroustrup के मुताबिक, अगर कुछ पैरामीटर वैकल्पिक हैं, यह करने के लिए एक आदर्श स्थिति है, उन्हें सूचक प्रकार, ताकि आप NULL पारित कर सकते हैं जब आप उन्हें के लिए बहस पारित करने के लिए की जरूरत नहीं है:

int CalculateStuff(int param1, int param2, int * result1, int * result2); 

और उपयोग:

int result = CalculateStuff(100, 42, NULL, NULL); 

अन्य सभी विकल्प इस के रूप में उतने अच्छे नहीं होंगे, या कम से कम इससे बेहतर बेहतर नहीं होंगे।

बेशक, CalculateStuff के कार्यान्वयन को पैरामीटर की जांच करनी है यदि वे NULL हैं या नहीं।

3

आप एक कक्षा बना सकते हैं जो int& पर अंतर्निहित (या स्पष्ट) रूपांतरण प्रदान करता है।

struct ignored 
{ 
    int n; 
    operator int&() { return n; } 
}; 

n = CalculateStuff(a, b, ignored(), ignored()); 

आप इसे एक टेम्पलेट बना सकते हैं और कॉन्स्ट अधिभार जोड़ सकते हैं।

+0

अनदेखा प्रकार का प्रकार नहीं होगा और आपको परेशानी होगी? –

+0

@ विंस्टनवेर्ट: क्यों? अस्थायी गैर-कॉन्स्ट संदर्भ से सीधे बाध्य नहीं हो सकता है। हालांकि, कोई भी गैर-कॉन्स्टेंस विधियों को कॉल कर सकता है अस्थायी वस्तु। यही वह लाभ उठा रहा है। – UncleBens

2

यह कानूनी है, लेकिन यह गारंटी नहीं है कि स्मृति को रिसाव न करें, उदाहरण के लिए प्रश्न 3 here देखें।

वैकल्पिक उत्पादन को लागू करने का सही और मुहावरेदार रास्ता एक सूचक पारित करने के लिए, NULL गुजर जब आप परिणाम नहीं करना चाहते, और सूचक के माध्यम से लिखने से पहले समारोह में NULL के लिए परीक्षण है।

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