2010-03-16 28 views
5

जब आप किसी ऑब्जेक्ट को प्रिंट करने जा रहे हैं, तो मित्र ऑपरेटर < < का उपयोग किया जाता है। क्या हम ऑपरेटर < < के लिए सदस्य फ़ंक्शन का उपयोग कर सकते हैं?ऑपरेटर के लिए सदस्य फ़ंक्शन को मित्र फ़ंक्शन क्यों पसंद किया जाता है <<

class A { 

public: 
void operator<<(ostream& i) { i<<"Member function";} 
friend ostream& operator<<(ostream& i, A& a) { i<<"operator<<"; return i;} 
}; 


int main() { 

    A a; 
    A b; 
    A c; 
    cout<<a<<b<<c<<endl; 
    a<<cout; 
    return 0; 
} 

एक मुद्दा यह है कि दोस्त समारोह इस

cout<<a<<b<<c 

क्या अन्य कारणों की तरह इसका इस्तेमाल करने के लिए सक्षम है?

+3

क्या आपको वास्तव में किसी अन्य कारण की आवश्यकता है? –

+0

@mmyers: मैं बस इसे जितना स्पष्ट कर सकता हूं उसे समझने की कोशिश करता हूं .... – skydoor

+1

यह स्पष्ट रूप से सदस्य कार्य नहीं हो सकता है (चार्ल्स बेली का जवाब देखें), लेकिन यह * दोस्त * नहीं होना चाहिए आप कक्षा के सार्वजनिक इंटरफ़ेस के संदर्भ में इसे कार्यान्वित कर सकते हैं, जो कि सुपर होगा। – UncleBens

उत्तर

11

आपको एक फ्री फ़ंक्शन का उपयोग करना है, न कि बाइनरी ऑपरेटरों के लिए सदस्य फ़ंक्शन नहीं है, बाएं हाथ की तरफ हमेशा *this सदस्य फ़ंक्शंस के लिए दाएं हाथ के साथ अन्य पैरामीटर के रूप में पारित किया जाता है।

आउटपुट स्ट्रीम ऑपरेटरों के लिए बाएं हाथ की तरफ हमेशा स्ट्रीम ऑब्जेक्ट होता है ताकि यदि आप एक मानक वर्ग में स्ट्रीम कर रहे हों और स्ट्रीम को स्वयं नहीं लिख रहे हैं तो आपको एक मुफ्त फ़ंक्शन प्रदान करना होगा, न कि आपकी कक्षा का सदस्य।

हालांकि यह संभव हो सकता है एक सदस्य समारोह के रूप में एक पीछे की ओर धारा ऑपरेटर प्रदान करते हैं और इस तरह से बाहर स्ट्रीम करने के लिए होगा:

myObject >> std::cout; 

न केवल आप एक बहुत मजबूत पुस्तकालय सम्मेलन का उल्लंघन होगा, जैसा कि आप बाहर बिंदु, चेनिंग उत्पादन ऑपरेशन >> के बाएं से दाएं समूह के कारण काम नहीं करेगा।

संपादित करें: दूसरों का उल्लेख किया है के रूप में, आप इसे एक नि: शुल्क समारोह यह केवल एक friend होने के लिए स्ट्रीमिंग समारोह वर्ग 'सार्वजनिक इंटरफ़ेस के मामले में लागू नहीं किया जा सकता है अगर जरूरत है बनाने के लिए है, जबकि।

10

आपके पास कोई विकल्प नहीं है - इसे एक नि: शुल्क फ़ंक्शन होना चाहिए।

नोट, हालांकि, यह आवश्यक नहीं है कि यह friend फ़ंक्शन हो। अगर आपको वास्तव में इसे निजी पहुंच प्रदान करने की ज़रूरत है तो इसे केवल एक दोस्त बनने की जरूरत है। उदाहरण के लिए, मैं प्रोग्रामिंग प्रतियोगिताओं में निम्नलिखित का उपयोग करें:

template <class A, class B> 
std::ostream& operator<<(std::ostream& os, const std::pair<A, B>& p) 
{ 
    return os << '(' << p.first << ", " << p.second << ')'; 
} 

कोई ज़रूरत नहीं यह first के रूप में दोस्त होने के लिए, और second सार्वजनिक रूप से सुलभ हैं।

1

आपके उदाहरण में एक और कारण - यह friend होना चाहिए क्योंकि कक्षा परिभाषा के अंदर एक नि: शुल्क फ़ंक्शन को परिभाषित करने का यही एकमात्र तरीका है। यदि आप एक गैर-मित्र मुक्त फ़ंक्शन चाहते थे, तो उसे कक्षा के बाहर परिभाषित करना होगा।

आप कक्षा में इसे परिभाषित क्यों करना पसंद करेंगे? कभी कभी यह सब ऑपरेटरों को एक साथ परिभाषित करने के लिए अच्छा है:

struct SomeClass { 
    // blah blah blah 
    SomeClass &operator+=(const SomeClass &rhs) { 
     // do something 
    } 
    friend SomeClass operator+(SomeClass lhs, const SomeClass &rhs) { 
     lhs += rhs; 
     return lhs; 
    } 
    // blah blah blah 
    // several pages later 
}; 

हो सकता है थोड़ा अधिक उपयोगकर्ता के अनुकूल से:

struct SomeClass { 
    // blah blah blah 
    SomeClass &operator+=(const SomeClass &rhs) { 
     // do something 
    } 
    // blah blah blah 
    // several pages later 
}; 

SomeClass operator+(SomeClass lhs, const SomeClass &rhs) { 
    lhs += rhs; 
    return lhs; 
} 

इस कोर्स है कि आप वर्ग परिभाषा संबंधित सदस्य कार्यों को परिभाषित कर रहे की हो जाती है , बल्कि उन्हें वहां घोषित करना और उन्हें .cpp फ़ाइल में परिभाषित करना।

संपादित करें: मैंने वास्तव में इसके बारे में सोचने के बिना + = और + उदाहरण के रूप में उपयोग किया है, लेकिन आपका प्रश्न operator<< है, जिसमें operator+ जैसे कोई करीबी संबंधित ऑपरेटर नहीं हैं। लेकिन अगर operator<< प्रिंटिंग से संबंधित एक या अधिक सदस्य फ़ंक्शंस को कॉल करता है, तो आप इसे परिभाषित कर सकते हैं जहां उन्हें परिभाषित किया गया है।

0

आप नहीं कर सकते। लेकिन यदि आप नहीं चाहते हैं कि यह एक मित्र कार्य हो, तो इसे एक मुफ्त कार्य करें और कक्षा के सार्वजनिक इंटरफ़ेस के संदर्भ में इसे कार्यान्वित करें। उदाहरण के लिए।

ostream& operator<<(ostream& os, Myclass& obj) 
{ 
    return obj.print(os); 
} 

ostream& MyClass::print(ostream& os) 
{ 
    os << val; // for example. 
    return os; 
} 
संबंधित मुद्दे

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