2010-09-02 19 views
13

मैं अपनी कक्षा के लिए operator<< अधिभारित करना चाहता हूं। क्या मुझे std नेमस्पेस में इस अधिभारित परिभाषा को जोड़ना चाहिए? (चूंकि ostream operator<<std नामस्थान का हिस्सा है) या क्या मुझे इसे वैश्विक नामस्थान में छोड़ देना चाहिए?गैर-सदस्य ऑपरेटर अधिभार कहां रखा जाना चाहिए?

संक्षेप में:

class MyClass { 

}; 

namespace std { 
    ostream& operator<< (ostream& Ostr, const MyClass& MyType) {} 
} 

या

class MyClass { 

}; 

std::ostream& operator<< (std::ostream& Ostr, const MyClass& MyType) {} 

कौन सा अधिक उपयुक्त है और क्यों है? आपकी प्रतिक्रिया के लिए अग्रिम में धन्यवाद।

उत्तर

25

आपको ऑपरेटर ओवरलोड को उसी श्रेणी में अपनी कक्षा के रूप में रखना चाहिए।

इस ऑपरेटर तर्क पर निर्भर देखने (ठीक है, वास्तव में, के बाद से ostream नाम स्थान std में है, अधिभार अधिभार भी अगर आप इसे नाम स्थान std में डाल पाया जा होगा का उपयोग कर अधिभार संकल्प के दौरान पाया जा सकता है, लेकिन वहाँ है की अनुमति देगा ऐसा करने का कोई कारण नहीं है)।

अच्छे डिजाइन प्रथाओं की दृष्टि से, ऑपरेटर अधिभार अधिक ostream के इंटरफेस की तुलना में अपने वर्ग के इंटरफ़ेस का एक हिस्सा है, तो यह अपने वर्ग के रूप में एक ही नाम स्थान में अंतर्गत आता है (यह भी हर्ब सुतर की Namespaces and the Interface Principle देखें)।

मानक मानकों-अनुपालन और पोर्टेबल कोड लिखने के दृष्टिकोण से, आप ऑपरेटर अधिभार को नेमस्पेस std में नहीं डाल सकते हैं। जबकि आप std नामस्थान में उपयोगकर्ता परिभाषित इकाइयों के लिए टेम्पलेट विशेषज्ञता जोड़ सकते हैं, तो आप अतिरिक्त फ़ंक्शन अधिभार नहीं जोड़ सकते हैं।

+1

+1 इसके अलावा, अनिवार्य लिंक: http://en.wikipedia.org/wiki/Argument-dependent_lookup –

+0

अंतिम वाक्य वास्तव में सही स्टैंडर्ड से सैम प्रतिक्रिया और उद्धरण विचार कर रहा है। – Chubsdad

+3

@chubsdad: हाँ, मुझे ऐसा लगता है: आप _can_ विशेषज्ञता जोड़ सकते हैं; आप overloads _can't_ जोड़ नहीं सकते हैं। –

6

मानक नामस्थान में जोड़ें न करें। कारण: यदि सभी ने ऐसा किया है, तो मानक नामस्थान में नाम संघर्षों का ढेर होगा, जो नामस्थान के उद्देश्य को हरा देता है।

आपका उद्देश्य आपकी कक्षा के लिए "ओस्ट्रीम-सक्षम" होना है। ऐसा करने के लिए मानक नेमस्पेस में होने की आवश्यकता नहीं है। जब तक यह आपकी कक्षा में जो भी नामस्थान घोषित किया गया है, तब तक आप ठीक हैं। मानक नामस्थान में इसे रखना बुरा अभ्यास होगा।

+1

यह 'std' नेमस्पेस के उद्देश्य को हरा देता है, जो सी ++ मानक लाइब्रेरी कोड के लिए है। कौन सा उपयोगकर्ता कोड नहीं है। –

6

इसे std नामस्थान में न जोड़ें, इसे अपनी कक्षा के समान नामस्थान में रखें। नामस्थान का उद्देश्य टकराव को रोकने के लिए है। मानक कहते हैं

17.4.3.1 सुरक्षित नाम

यह एक सी ++ करने के लिए कार्यक्रम जब तक अन्यथा निर्दिष्ट नाम स्थान एसटीडी भीतर नाम स्थान एसटीडी करने के लिए घोषणाओं या परिभाषाओं या नामस्थान जोड़ने के लिए अनिर्धारित रहता है। एक प्रोग्राम नामस्थान std पर किसी मानक लाइब्रेरी टेम्पलेट के लिए टेम्पलेट विशेषज्ञता जोड़ सकता है। इस तरह के एक विशेषज्ञता अपरिभाषित व्यवहार में एक मानक पुस्तकालय टेम्पलेट परिणामों के (पूर्ण या आंशिक ) जब तक घोषणा बाहरी लिंकेज के उपयोगकर्ता परिभाषित नाम पर निर्भर करता है और जब तक विशेषज्ञता मूल के लिए मानक पुस्तकालय आवश्यकताओं को पूरा टेम्पलेट।

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