यह आम तौर पर सबसे अच्छा अभ्यास की सिफारिश की जा करने के लिए इस्तेमाल 1 करने के लिए के लिए स्थिरांक रेफरी द्वारा उपयोग के पास सभी प्रकार , प्रकार (builtin के अलावा char
, int
, double
, आदि), iterators के लिए और समारोह वस्तुओं के लिए (lambdas, से पाने कक्षाएं std::*_function
)।
चाल शब्दार्थ के अस्तित्व से पहले यह विशेष रूप से सच था । कारण सरल है: यदि आप मूल्य से गुजरते हैं, तो वस्तु की एक प्रति बनाई जानी चाहिए और, बहुत छोटी वस्तुओं को छोड़कर, यह हमेशा एक संदर्भ पारित करने की तुलना में अधिक महंगा है।
C ++ 11 के साथ, हमने चाल शब्दार्थ हासिल किए हैं । संक्षेप में, शब्दार्थ को अनुमति दें कि, कुछ मामलों में, किसी वस्तु को बिना कॉपी किए "मूल्य से" पारित किया जा सकता है। विशेष रूप से, यह मामला है जब आप जिस वस्तु से गुजर रहे हैं, वह एक प्रतिद्वंद्विता है ।
अपने आप में, किसी वस्तु को स्थानांतरित करना अभी भी कम से कम उतना ही महंगा है जितना कि संदर्भ से गुजरना। हालांकि, कई मामलों में एक फ़ंक्शन आंतरिक रूप से किसी भी वस्तु की नकल करेगा - अर्थात यह तर्क का स्वामित्व लेगा । 2
इन स्थितियों में हमारे पास निम्नलिखित (सरलीकृत) व्यापार बंद हैं:
- हम ऑब्जेक्ट को संदर्भ द्वारा पास कर सकते हैं, फिर आंतरिक रूप से कॉपी कर सकते हैं।
- हम वस्तु को मूल्य से पास कर सकते हैं।
"मूल्य से गुजारें" तब भी वस्तु को कॉपी करने का कारण बनता है, जब तक कि वस्तु एक प्रतिद्वंद्विता न हो। एक प्रतिद्वंद्विता के मामले में, वस्तु को इसके बजाय स्थानांतरित किया जा सकता है, ताकि दूसरा मामला अचानक "कॉपी, फिर" नहीं हो, लेकिन "स्थानांतरित करें, फिर (संभावित) फिर से चलें"।
बड़ी वस्तुओं के लिए जो उचित चाल वाले कंस्ट्रक्टर (जैसे वैक्टर, स्ट्रिंग्स…) को लागू करते हैं, दूसरा मामला पहले की तुलना में बहुत अधिक कुशल होता है। इसलिए, फ़ंक्शन द्वारा तर्क का स्वामित्व लेने पर मान का उपयोग करने की अनुशंसा की जाती है , और यदि ऑब्जेक्ट प्रकार कुशल मूविंग का समर्थन करता है ।
एक ऐतिहासिक नोट:
वास्तव में, किसी भी आधुनिक संकलक को यह पता लगाने में सक्षम होना चाहिए कि मूल्य से गुजरना महंगा है या नहीं, और यदि संभव हो तो एक कॉन्स्ट रेफरी का उपयोग करने के लिए कॉल को रूपांतरित करें।
सिद्धांत रूप में। व्यवहार में, कंपाइलर हमेशा फ़ंक्शन के बाइनरी इंटरफ़ेस को तोड़ने के बिना इसे बदल नहीं सकते हैं। कुछ विशेष मामलों में (जब फ़ंक्शन को इनलाइन किया जाता है) तो प्रतिलिपि वास्तव में बढ़ाई जाएगी यदि कंपाइलर यह पता लगा सकता है कि फ़ंक्शन में क्रियाओं के माध्यम से मूल ऑब्जेक्ट को नहीं बदला जाएगा।
लेकिन सामान्य तौर पर कंपाइलर इसे निर्धारित नहीं कर सकते हैं, और C ++ में मूवमेंट शब्दार्थ के आगमन ने इस अनुकूलन को बहुत कम प्रासंगिक बना दिया है।
स्कॉट मेयर्स में 1 ईजी, प्रभावी सी ++ ।
2 यह विशेष रूप से अक्सर ऑब्जेक्ट कंस्ट्रक्टर्स के लिए सच है, जो तर्क ले सकते हैं और उन्हें आंतरिक रूप से निर्मित ऑब्जेक्ट की स्थिति का हिस्सा बनने के लिए स्टोर कर सकते हैं।