2011-06-06 13 views
26

कुछ पुस्तकों में और अक्सर इंटरनेट के आसपास मुझे "operator==" जैसे मित्र के रूप में घोषित किया जाना चाहिए "।क्या ऑपरेटरों को दोस्तों के रूप में घोषित किया जाना चाहिए?

मुझे कैसे समझना चाहिए कि ऑपरेटर को मित्र के रूप में घोषित किया जाना चाहिए और जब इसे सदस्य के रूप में घोषित किया जाना चाहिए? ऑपरेटरों को == और << के अलावा अक्सर दोस्तों के रूप में घोषित करने की आवश्यकता होगी?

+0

गैर-सदस्य कार्य जिन्हें निजी वर्ग के सदस्यों तक पहुंच की आवश्यकता है, वे मित्र बनने की आवश्यकता है। – AJG85

+3

@ AJG85: सच है, लेकिन मुझे लगता है कि प्रश्न कब सदस्यों को चुनना है, और जब गैर-सदस्यों को चुनना है (यदि आवश्यक हो तो उन्हें दोस्त बनाना)। –

+1

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

उत्तर

28

यह वास्तव में इस बात पर निर्भर करता है कि कॉल के बाईं ओर या दाएं हाथ की तरफ operator== (या अन्य ऑपरेटर) पर जा रहा है या नहीं। यदि एक वर्ग अभिव्यक्ति के दायीं तरफ होने वाला है- और एक प्रकार के लिए एक अंतर्निहित रूपांतरण प्रदान नहीं करता है जिसे बाएं हाथ की तुलना में तुलना की जा सकती है- आपको operator== को एक अलग कार्य के रूप में या एक के रूप में लागू करने की आवश्यकता है कक्षा के friend। यदि ऑपरेटर को निजी कक्षा डेटा तक पहुंचने की आवश्यकता है, तो को friend के रूप में घोषित किया जाना चाहिए।

उदाहरण के लिए,

class Message { 
    std::string content; 
public: 
    Message(const std::string& str); 
    bool operator==(const std::string& rhs) const; 
}; 

आप

Message message("Test"); 
std::string msg("Test"); 
if (message == msg) { 
    // do stuff... 
} 

नहीं बल्कि दूसरी तरह के आसपास

if (msg == message) { // this won't compile 

आप एक दोस्त की घोषणा करने की जरूरत है एक स्ट्रिंग के लिए एक संदेश की तुलना कर सकते operator== कक्षा

012 के अंदर अगर वे अकेले वर्ग डेटा का उपयोग नहीं करता है
class Message { 
    std::string content; 
public: 
    Message(const std::string& str); 
    bool operator==(const std::string& rhs) const; 
    friend bool operator==(const std::string& lhs, const Message& rhs); 
}; 

या उचित प्रकार

class Message { 
    std::string content; 
public: 
    Message(const std::string& str); 
    bool operator==(const std::string& rhs) const; 
    operator std::string() const; 
}; 

या एक अलग समारोह की घोषणा है, जो एक दोस्त होने की जरूरत नहीं है के लिए एक अंतर्निहित रूपांतरण ऑपरेटर की घोषणा

bool operator==(const std::string& lhs, const Message& rhs); 
+3

अच्छा जवाब, लेकिन आपको कक्षा परिभाषा के बाहर मित्र फ़ंक्शन घोषित करने की आवश्यकता नहीं है। कक्षा के अंदर एक एकल 'मित्र' घोषणा (यदि आपको पसंद है तो इनलाइन परिभाषा के साथ) पर्याप्त है। –

+0

@ माइक हू, आप सही हैं। किसी कारण से, मुझे नहीं लगता था कि वह वैध वाक्यविन्यास था ... –

19

जब आपके पास कक्षा के बाहर आपके ऑपरेटर होते हैं, तो दोनों पैरामीटर निहित प्रकार रूपांतरणों में भाग ले सकते हैं (जबकि ऑपरेटर बी के साथ कक्षा शरीर में परिभाषित ईिंग, केवल दाएं हाथ के संचालन कर सकते हैं)। आम तौर पर, यह सभी क्लासिक बाइनरी ऑपरेटरों (यानी ==, !=, +, -, <<, ...) के लिए एक लाभ है।

बेशक आपको केवल अपनी कक्षा के ऑपरेटरों को friend एस घोषित करना चाहिए यदि आपको आवश्यकता है कि वे पूरी तरह से कक्षा के सार्वजनिक सदस्यों के आधार पर अपने परिणाम की गणना नहीं करते हैं।

7

आम तौर पर, केवल ऑपरेटर जो निःशुल्क कार्यों के रूप में कार्यान्वित किए जाते हैं जिन्हें वास्तव में कक्षा के निजी या संरक्षित डेटा तक पहुंचने की आवश्यकता होती है, जिन्हें वे संचालित करते हैं, अन्यथा उन्हें गैर-सदस्य गैर-सदस्य कार्य होना चाहिए।

आम तौर पर, केवल एकमात्र ऑपरेटरों जिन्हें मैं सदस्य कार्यों के रूप में कार्यान्वित करता हूं वे मूल रूप से असमान होते हैं और जहां ऑपरेटरों के बराबर भूमिका नहीं होती है।जिन सदस्यों को मैं सदस्यों के रूप में कार्यान्वित करना चाहता हूं वे हैं सदस्यों के लिए आवश्यक: सरल असाइनमेंट, (), [] और -> यौगिक असाइनमेंट ऑपरेटर, यूनरी ऑपरेटरों और शायद << और >> के कुछ ओवरलोड के साथ स्ट्रीम जो स्वयं स्ट्रीम या स्ट्रीम-जैसी हैं कक्षाएं। मैंने &&, || या , कभी अधिभारित नहीं किया।

अन्य सभी ऑपरेटर मैं नि: शुल्क कार्यों के रूप में कार्यान्वित करने के लिए प्रवृत्त होते हैं, अधिमानतः उन कक्षाओं के सार्वजनिक इंटरफ़ेस का उपयोग करते हैं जो वे संचालित करते हैं, केवल आवश्यक होने पर दोस्तों के रूप में वापस आते हैं।

ऑपरेटरों रखते हुए इस तरह के !=, ==, <, +, /, आदि गैर सदस्य कार्यों के रूप में के रूप में आश्चर्य की बात विषमताओं की संख्या कम करने में मदद करता है जो निहित रूपांतरण दृश्यों के संबंध में छोड़ दिया और सही ऑपरेंड के समान उपचार सक्षम बनाता है।

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

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