2010-07-05 22 views
19

मैं यह सुनिश्चित करना चाहता हूं कि मैं पास-बाय-वैल्यू बनाम पास-बाय-रेफरेंस को सही ढंग से समझूं। विशेष रूप से, मैं किसी ऑब्जेक्ट के लिए वृद्धि ++ ऑपरेटर के उपसर्ग/पोस्टफिक्स संस्करणों को देख रहा हूं।उपसर्ग/पोस्टफिक्स वृद्धि ऑपरेटर

चलिए मान लीजिए हम निम्नलिखित वर्ग X है:,

class X{ 
private: 
    int i; 
public: 
X(){i=0;} 
X& operator ++(){ ++i; return *this; } //prefix increment 

X operator ++ (int unused){ //postfix increment 
    X ret(*this); 
    i++; 
    return ret; 
} 

operator int(){ return i; } //int cast 
}; 

सबसे पहले मैं उपसर्ग/पोस्टफ़िक्स वेतन वृद्धि ऑपरेटरों ठीक से लागू किया गया है?

दूसरा, उपसर्ग ऑपरेटर की तुलना में पोस्टफिक्स ऑपरेटर कितना मेमोरी-कुशल है? विशेष रूप से कितने X ऑब्जेक्ट प्रतियां बनाई जाती हैं जब ऑपरेटर के प्रत्येक संस्करण का उपयोग किया जाता है?

रिटर्न-बाय-रेफरेंस बनाम रिटर्न-बाय-वैल्यू के साथ वास्तव में क्या होता है, इसकी व्याख्या मुझे समझने में मदद कर सकती है।


संपादित करें: उदाहरण के लिए, निम्न कोड के साथ ...

X a; 
X b=a++; 

... ए और बी अब उपनाम कर रहे हैं?

+0

पोस्टफिक्स ऑपरेटर में पोस्टफिक्स-वृद्धि 'i' पोस्ट करने की कोई आवश्यकता नहीं है। असल में, मैं [फ्रेडओवरफ्लो सुझाव देता हूं] (http://stackoverflow.com/questions/3181211/3181359#3181359) और उपसर्ग संस्करण को कॉल करता हूं। आईएमओ जो वास्तव में वृद्धि को फिर से कार्यान्वित करने से अधिक मूर्खतापूर्ण है (भले ही कार्यान्वयन यहां छोटा हो)। _ और उस अंतर्निहित रूपांतरण ऑपरेटर से छुटकारा पाएं ._ यह आपको अन्यथा चोट पहुंचाने जा रहा है। (तीसरे और आखिरी बार मैंने एक निहित रूपांतरण ऑपरेटर लिखा था 2001 में और एक या दो साल बाद मुझे पता चला कि इससे सूक्ष्म बग पैदा हुईं और इसे हटा दिया गया - जैसे सभी पहले। बीटीडीटीजीटीएलएस।) – sbi

उत्तर

17

यह एक सही कार्यान्वयन है। यह सामान्य है कि पोस्टफिक्स ऑपरेटर प्रदर्शन पर और भी खराब होगा क्योंकि आपको वृद्धि करने से पहले एक और प्रतिलिपि बनाना है (और यही वजह है कि मुझे हमेशा उपसर्ग का उपयोग करने की आदत में नहीं मिला है जब तक कि मुझे कुछ और चाहिए)।

रिटर्न-बाय-रेफरेंस के साथ, आप वर्तमान ऑब्जेक्ट के लिए एल-वैल्यू संदर्भ लौट रहे हैं। संकलक आमतौर पर वर्तमान वस्तु के पते को वापस कर इसे कार्यान्वित करेगा। इसका मतलब है कि ऑब्जेक्ट को वापस करना एक नंबर लौटने जैसा आसान है।

हालांकि, वापसी-दर-मूल्य के साथ, एक प्रतिलिपि की जानी चाहिए। इसका मतलब है कि वापसी के दौरान प्रतिलिपि बनाने के लिए और केवल एक पते के बजाय प्रतिलिपि बनाने के लिए अधिक जानकारी है। यह वह जगह है जहां आपका प्रदर्शन हिट आता है।

आपके कार्यान्वयन की दक्षता सामान्य कार्यान्वयन के साथ-साथ दिखती है।

संपादित करें: आपके परिशिष्ट के संबंध में, नहीं, वे उपनाम नहीं हैं। आपने दो अलग-अलग वस्तुओं को बनाया है। जब आप मान से वापस आते हैं (और जब आपने पोस्टफिक्स वृद्धि ऑपरेटर के भीतर से एक नई ऑब्जेक्ट बनाई है) तो यह नया ऑब्जेक्ट एक अलग स्मृति स्थान में रखा गया है।

int a = 0; 
int& b = ++a; 

ख एक पते जो एक संदर्भ देता है:

हालांकि, निम्नलिखित कोड, ए और बी में उपनाम कर रहे हैं।

+2

सामान्य रूप से सही, मॉड्यूल संभव वापसी मूल्य अनुकूलन (http://en.wikipedia.org/wiki/Return_value_optimization)। –

2

आपके ऑपरेटरों को सही ढंग से लागू किया गया है।

उपसर्ग ऑपरेटर में, एक्स की कोई प्रतियां नहीं बनाई गई हैं।

पोस्टफ़िक्स ऑपरेटर में, एक प्रति सेवानिवृत्त के लिए बना है, और संभावित दूसरी प्रतिलिपि जब समारोह से लौट रहे जाता है, लेकिन सभी compilers इस प्रति छिपाना होगा।

X operator++(int) 
{ 
    X copy(*this); 
    ++*this;   // call the prefix increment 
    return copy; 
} 

एक X वस्तु बढ़ाने के तर्क इस प्रकार केवल उपसर्ग संस्करण के अंदर निहित है:

15

यह वस्तु ही का उपसर्ग वेतन वृद्धि पोस्टफ़िक्स वेतन वृद्धि में कॉल करने के लिए और अधिक मुहावरेदार है।

+0

हाँ, यह मुझे एक ही सुधार पोस्ट करने से मुक्त करता है। मुझसे + 1' – sbi

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