2010-11-03 12 views
29

पर निर्माता ले जाएँ, और आधार वस्तु भी अर्थ विज्ञान के लिए कदम है, उचित तरीके से ली गई वस्तु चाल निर्माता से आधार वस्तु चाल निर्माता कॉल करने के लिए क्या है?व्युत्पन्न वस्तु

मैं पहली बार सबसे स्पष्ट बात करने की कोशिश की:

Derived(Derived&& rval) : Base(rval) 
{ } 

हालांकि, इस आधार वस्तु की प्रतिलिपि निर्माता बुला खत्म करने लगता है। तब मैं स्पष्ट रूप से यहाँ std::move उपयोग करते हुए, इस तरह की कोशिश की:

Derived(Derived&& rval) : Base(std::move(rval)) 
{ } 

यह काम किया, लेकिन मैं उलझन में हूँ क्यों यह आवश्यक है। मैंने सोचा std::move केवल एक रैल्यू संदर्भ देता है। लेकिन चूंकि इस उदाहरण में rval पहले से ही एक रावल्यू संदर्भ है, std::move पर कॉल अनिवार्य होना चाहिए। लेकिन अगर मैं यहां std::move का उपयोग नहीं करता हूं, तो यह सिर्फ कॉपी कन्स्ट्रक्टर को कॉल करता है। तो std::move पर कॉल क्यों आवश्यक है?

उत्तर

29

rval एक rvalue नहीं है। यह चालक कन्स्ट्रक्टर के शरीर के अंदर एक लालसा है। यही कारण है कि हमें स्पष्ट रूप से std :: move का आह्वान करना होगा।

this देखें। महत्वपूर्ण नोट ऊपर

ध्यान दें कि तर्क एक्स कदम कार्यों के लिए एक lvalue आंतरिक रूप में व्यवहार किया है, भले ही यह एक rvalue संदर्भ पैरामीटर के रूप में घोषित किया है। कारण है कि यह कहने के लिए आवश्यक है कि इस कदम (एक्स) के बजाय सिर्फ x जब आधार वर्ग के लिए नीचे गुजर। यह कदम गलती से कुछ नामित चर से दो बार चलती रोकने के लिए डिज़ाइन अर्थ विज्ञान का एक महत्वपूर्ण सुरक्षा सुविधा है। सभी चालें केवल rvalues ​​से पाए जाते हैं, या एक स्पष्ट डाली साथ std :: चाल का उपयोग कर के रूप में इस तरह के rvalue करने के लिए। यदि आपके पास चर के लिए एक नाम है, तो यह एक लवली है।

+0

यदि आप नियमित लवल्यू (std :: move (xx) का उपयोग नहीं करते हैं) के रूप में एक तर्क इनपुट प्रदान करते हैं तो बस कन्स्ट्रक्टर के बावजूद एक नोट जोड़ने के लिए आपको एक कार्य के लिए Xyy 'lvalue' Xyy && 'में बाध्य नहीं किया जा सकता है foo (Xyy && xyy) के रूप में परिभाषित किया गया है। –

0

आपको वास्तव में std :: move (obj) के बजाय std :: forward (obj) का उपयोग करना चाहिए। आगे ओबीजे के आधार पर उचित रैवल्यू या लवल्यू वापस कर देगा जबकि चाल एक लालसा को एक रावल्यू में बदल देगी।

+10

इस संदर्भ में आप हमेशा एक रावल्यू को डालना चाहते हैं। –

+2

तो असली इरादा आगे बढ़ता है जो वास्तव में आगे बढ़ने के लिए पारित किया गया था। आगे () ठीक है। आपको सभी आधार कार्यों को बुलाए जाने के लिए इसका उपयोग करने के अभ्यास में भी शामिल होगा, इससे कोई फर्क नहीं पड़ता कि क्या हो रहा है। कॉल करने की आदत में आने से) गलतियों को उत्पन्न हो सकता है जो पता लगाना मुश्किल हो सकता है। अगर आप चाहें तो यह आसान हो जाता है एक फ़ंक्शन पर टेम्पलेट का उपयोग करें जो एक रावल्यू और एक लालसा दोनों पर कार्य कर सकता है। यदि यह फ्यूशन गलत रूप से किसी ऑब्जेक्ट में पारित किया गया था जो एक लालसा है, तो यह सी ontinue निष्पादन? सिर्फ शैतानों को खेलना थोड़ा सा – jbreiding

+1

@jbreiding मैं इस में से किसी को भी समझ नहीं पा रहा हूं ... जब std :: move विफल हो जाएगा, तो कुछ कोड नमूने के साथ आपकी व्याख्या पर विस्तारित करें, क्यों std :: आगे पसंद किया जाता है और इसका उपयोग कब किया जाता है? – aCuria

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