2012-11-08 10 views
5

मुझे लगता है कि फ़ंक्शन में पहले से ही एक वापसी मूल्य है ताकि इसे जोड़ा नहीं जा सके।मौजूदा कोड को तोड़ने के बिना मैं फ़ंक्शन में आउटपुट पैरामीटर कैसे जोड़ सकता हूं?

मैं इस समस्या को हल करने के लिए क्या आया था अतिरिक्त पॉइंटर पैरामीटर जो डिफ़ॉल्ट रूप से nullptr को जोड़ना है।

से पहले:

bool fun(double a, std::vector<std::randomexample> const & b) 

के बाद:

bool fun(double a, std::vector<std::randomexample> const & b, int* extraoutput = nullptr) 

और इस

if(extraoutput) 
    *extraoutput = whatever; 

की तरह उपयोग लेकिन वह सिर्फ तुम क्या मैं के साथ आया है। मैं जानना चाहता हूं कि ऐसा करने का एक बेहतर तरीका है या नहीं। ध्यान दें कि "जो कुछ भी पहले से ही फ़ंक्शन में है।

+1

उचित लगता है। –

+1

यदि आप बिल्कुल मौजूदा चीज़ को बदलना नहीं चाहते हैं, तो एक नया ओवरलोडेड बनाएं। –

उत्तर

4

किसी कारण से आप द्विआधारी के साथ-साथ (अधिकतर) स्रोत अनुकूलता [*] की जरूरत है:

से पहले:

bool fun(double a, std::vector<std::randomexample> const & b) { 
    // do stuff 
    return true; 
} 

के बाद:

bool fun(double a, std::vector<std::randomexample> const & b, int* extraoutput) { 
    // do stuff 
    if(extraoutput) 
     *extraoutput = whatever; 
    return true; 
} 
bool fun(double a, std::vector<std::randomexample> const & b) { 
    return fun(a, b, nullptr); 
} 

आप तो फ़ंक्शन ओवरलोडिंग नहीं चाहते हैं (उदाहरण के लिए यदि funextern "C" का हिस्सा है I nterface), तो आपको वास्तव में नया फ़ंक्शन fun पर कॉल नहीं करना है। यह fun2 भी हो सकता है।

[*] जैसा कि एंड्रीटी बताता है, आपके समाधान की स्रोत संगतता सीमित है। आपके पुराने फ़ंक्शन पर कॉल आपके नए फ़ंक्शन को ठीक से कॉल करेंगे, लेकिन कुछ अन्य चीजें जो आप पुराने फ़ंक्शन के साथ कर सकते हैं ठीक काम नहीं करेंगे (क्योंकि आपने अपना प्रकार बदल दिया है)।

वास्तव में मेरे कोड में एक स्रोत असंगतता भी है। अधिभार को जोड़ने से पहले void(*foo)() = (void(*)()) fun; की अनुमति है, लेकिन बाद में यह संदिग्ध है। यदि आप उस कोड का समर्थन करना चाहते हैं जो ऐसा करता है, तो यह दूसरा कारण है कि फ़ंक्शन ओवरलोडिंग नहीं करना चाहते हैं।

+0

पुराने फ़ंक्शन का प्रकार क्यों बदल गया? मेरा मतलब है, पुराना फ़ंक्शन अब केवल नए फ़ंक्शन को कॉल करता है, इसलिए सामग्री बदल गई है लेकिन मुझे नहीं पता कि प्रकार क्यों बदल गया। – Sarien

+0

@ कॉरपोरल: आपके फ़ंक्शन का प्रकार 'बूल मजेदार (डबल ए, फू कॉन्स एंड बी) 'बूल (डबल, फू कॉन्स एंड)' है। आपके फ़ंक्शन का प्रकार 'बूल मज़े (डबल ए, फू कॉन्स एंड बी, इंट * अतिरिक्त आउटपुट = नलप्टर) 'बूल (डबल, फू कॉन्स एंड, इंट *)' है। दोनो एक जैसे नहीं हैं। मेरे कोड में, अभी भी एक नया फ़ंक्शन के अलावा 'बूल (डबल, फू कॉन्स्ट एंड) '* के साथ एक फ़ंक्शन है, इसलिए पुराना प्रकार पर निर्भर कोड ठीक है। –

+0

आह, ठीक है, तो यह वास्तव में आपके समाधान में एक समस्या नहीं है बल्कि मेरे अंदर है। क्षमा करें, उलझन में आया। :) – Sarien

-1

आप जेनेरिक ऑब्जर्वर पैटर्न को लागू करने का प्रयास कर सकते हैं। यहां एक जैसा है: http://sourcemaking.com/design_patterns/observer

भविष्य के लिए यह बेहतर होगा जब आप अधिक पैरामीटर जोड़ना चाहेंगे। यदि आप पैरामीटर के रूप में गुजरने के बाद प्राप्त नहीं कर सकते हैं तो समाधान भी होगा।

जैसा कि मैं समझता हूं कि आपको इसे इस फ़ंक्शन में करना है, अन्यथा हाँ अधिभार एक अच्छा समाधान है।

यह अन्य समाधान के लिए अन्यथा बाइनरी स्थिरता तोड़ता नहीं है।

+1

क्या यह वर्तमान मामले के लिए वास्तव में प्रासंगिक है? –

+0

अधिक सामान्य समाधान हमेशा एक मामला है, मैं भविष्य के लिए सोचता हूं जब खेल में अधिक पैरामीटर आ सकते हैं। – CyberGuy

+0

@ कथुलु: यह हो सकता है। अब एक वैकल्पिक नया पैरामीटर जोड़ें, जिसमें वर्तमान में 'निरीक्षण करें' फ़ंक्शन है। जब एक ही चीज़ फिर से होती है, तो आपको फ़ंक्शन में * अन्य * वैकल्पिक सूचक पैरामीटर जोड़ने की ज़रूरत नहीं है, इसके बजाय आप पर्यवेक्षक को एक और फ़ंक्शन जोड़ सकते हैं। –

0

जैसा कि दूसरों ने कहा है, यह आपका अंतिम उत्पाद होगा।

bool fun(double a, std::vector<std::randomexample> const & b){ 
    return fun(a,b,0); 
} 
bool fun(double a, std::vector<std::randomexample> const & b, int* extraoutput = 0){ 
    // have fun! 
    if(extraoutput) *extraoutput = whatever; 
    return true; 
} 
+0

डिफ़ॉल्ट तर्क क्यों? – xtofl

+1

उस स्थिति में आपको डिफ़ॉल्ट तर्क को हटाना होगा, क्योंकि अन्यथा 2 तर्कों के साथ कॉल संदिग्ध हो जाएगा। – AnT

+0

शायद नए फ़ंक्शन में उस अतिरिक्त आउटपुट को बनाना और इसे संदर्भ के रूप में पास करना अच्छा विचार होगा। कुछ प्रतिलिपि बचाने में सक्षम हो सकता है और कॉल अब अस्पष्ट नहीं होगा। – Sarien

2

आम तौर पर, मैं अतिरिक्त पैरामीटर के साथ एक विधि जोड़ने और कॉल पूर्व विधि से एक डिफ़ॉल्ट मान के साथ कि एक:

//foo v1 
void foo(S s) { 
    ... stuff with s; 
}; 

//codeA_v1: 
S s; 
foo(s); 

//codeB_v1 
S s2; 
foo(s2); 

फिर, मैं एक अतिरिक्त पैरामीटर के साथ एक पद्धति जोड़ें:

void foo(S s){ foo(s, default_value_for_T); } 
void foo(S s, T t){ 
    ... stuff with s and t 
} 

//codeA_v1 == codeA_v2 
S s; 
foo(s); 

//codeB_v2 
S s; 
T t; 
foo(s,t); 
2

यह एक विस्तृत टिप्पणी है। दूसरों द्वारा सुझाए गए अलंक के रूप में, आप स्रोत और बाइनरी संगतता दोनों प्रदान करने के लिए फ़ंक्शन को अधिभारित कर देंगे। ऐसा करने का कारण यह है कि फ़ंक्शन हस्ताक्षर में बदलाव शुरू करके, आप उलझन वाले प्रतीक नाम को भी बदलते हैं, उदा। _Z3fundRKSt6vectorISt13randomexampleSaIS0_EE से _Z3fundRKSt6vectorISt13randomexampleSaIS0_EEPi तक। यह अन्य सभी वस्तुओं के साथ बाइनरी संगतता को तोड़ देगा जो fun() को अपने पुराने उलझन वाले नाम से कॉल करते हैं। यदि fun() एक गतिशील रूप से लिंक्ड लाइब्रेरी का हिस्सा है, तो यह सभी मौजूदा बाइनरी को तोड़ देगा जो इसके खिलाफ लिंक करते हैं क्योंकि गतिशील लिंकर अब _Z3fundRKSt6vectorISt13randomexampleSaIS0_EE प्रतीक संदर्भ को हल करने में सक्षम नहीं होगा। यदि आप ओवरलोडेड फ़ंक्शन संस्करण के साथ जाते हैं, तो पुराना उलझन वाला प्रतीक अभी भी मौजूद होगा और बाइनरी संगतता बरकरार रहेगी।

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

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