दिलचस्प पोस्ट
आप अपनी प्राथमिक कुंजी कैसे पसंद करते हैं? डेलाइट बचत समय और समय क्षेत्र सर्वोत्तम अभ्यास iPhone कीबोर्ड कवर UITextField चेतावनी: असुरक्षित दुनिया लिखने योग्य dir / usr / local / bin PATH मोड, 040777 मोड JSlider के स्लाइडर आइकन को चित्रित करना JQuery: रिसाइज़ इवेंट को कैसे कॉल करें, केवल एक बार इसे पूर्ण होने के बाद रीसाइज किया जाए? एक सरणी स्थिति को एक सरणी स्थिति से दूसरे में ले जाएँ मैं जावास्क्रिप्ट में शून्य मानों की जांच कैसे करूं? अजीब जावा हैश फ़ंक्शन को समझना फ़ाइल या असेंबली को लोड नहीं किया जा सका या इसके निर्भरता में से एक जावास्क्रिप्ट में हजारों विभाजक के रूप में संख्या को कैसे मुद्रित किया जाए जावास्क्रिप्ट में ऑब्जेक्ट हटाना आईओएस स्विफ्ट में एक छवि में मैं टेक्स्ट कैसे जोड़ूं? जावा में पुरातन के लिए संदर्भ से पास के बराबर कैसे करें सी # में चर गुंजाइश

ऑपरेटर को << एक मित्र के रूप में या एक सदस्य समारोह के रूप में लागू किया जाना चाहिए?

यह मूल रूप से सवाल है, क्या operator<< को लागू करने का एक "सही" तरीका है operator<< ? इसे पढ़ कर मैं देख सकता हूं कि ऐसा कुछ:

 friend bool operator<<(obj const& lhs, obj const& rhs); 

कुछ पसंद है पसंद है

 ostream& operator<<(obj const& rhs); 

लेकिन मैं काफी नहीं देख सकता कि मुझे एक या दूसरे का उपयोग क्यों करना चाहिए

मेरा व्यक्तिगत मामला है:

 friend ostream & operator<<(ostream &os, const Paragraph& p) { return os << p.to_str(); } 

लेकिन शायद मैं ऐसा कर सकता था:

 ostream & operator<<(ostream &os) { return os << paragraph; } 

इस निर्णय पर मुझे किस आधार पर आधार होना चाहिए?

नोट :

  Paragraph::to_str = (return paragraph) 

जहां पैराग्राफ एक स्ट्रिंग है

वेब के समाधान से एकत्रित समाधान "ऑपरेटर को << एक मित्र के रूप में या एक सदस्य समारोह के रूप में लागू किया जाना चाहिए?"

यहां समस्या आपके द्वारा लिखे गए आलेख के आपके व्याख्या में है।

यह लेख किसी ऐसे व्यक्ति के बारे में है जो कि बूल रिलेशन ऑपरेटर को ठीक से परिभाषित कर रहा है।

परिचालक:

  • समानता == और! =
  • रिश्ते <> <=> =

इन ऑपरेटरों को एक बूल वापस करना चाहिए क्योंकि वे उसी प्रकार की दो ऑब्जेक्ट्स की तुलना कर रहे हैं। कक्षा के हिस्से के रूप में इन ऑपरेटरों को परिभाषित करना आमतौर पर आसान होता है इसका कारण यह है कि एक कक्षा स्वत: स्वयं का मित्र है, इसलिए प्रकार पैराग्राफ के ऑब्जेक्ट एक-दूसरे की जांच कर सकते हैं (एक दूसरे के निजी सदस्य भी)।

इन निशुल्क खड़े कार्यों को बनाने के लिए एक तर्क है क्योंकि यह स्वत: रूपांतरण दोनों पक्षों को रूपांतरित करता है यदि वे समान प्रकार के नहीं हैं, जबकि सदस्य कार्य केवल आरएएस को स्वत: परिवर्तित करने की अनुमति देते हैं। मुझे यह एक पेपर मैन तर्क मिलता है क्योंकि आप वास्तव में स्वयं रूपांतरण पहली जगह (आमतौर पर) में नहीं चाहते हैं लेकिन अगर ऐसा कुछ है जो आप चाहते हैं (मैं इसकी अनुशंसा नहीं करता) तो तुलनात्मक मुक्त खड़े करना फायदेमंद हो सकता है

स्ट्रीम ऑपरेटर:

  • ऑपरेटर << आउटपुट
  • ऑपरेटर >> इनपुट

जब आप इन्हें स्ट्रीम ऑपरेटर (बाइनरी पारी के बजाय) के रूप में उपयोग करते हैं तो पहला पैरामीटर एक स्ट्रीम होता है। चूंकि आपके पास स्ट्रीम ऑब्जेक्ट तक पहुंच नहीं है (यह आपके को संशोधित करने के लिए नहीं है) ये सदस्य ऑपरेटर नहीं हो सकते हैं, जिन्हें वे क्लास के बाहर होना चाहिए। इस प्रकार उन्हें या तो कक्षा के मित्र होना चाहिए या किसी सार्वजनिक विधि का उपयोग करना चाहिए जो आपके लिए स्ट्रीमिंग करेंगे।

यह इन ऑब्जेक्ट्स के लिए एक परंपरागत ऑब्जेक्ट के संदर्भ को वापस करने के लिए भी पारंपरिक है ताकि आप एक साथ श्रृंखला स्ट्रीम संचालन कर सकें।

 #include <iostream> class Paragraph { public: explicit Paragraph(std::string const& init) :m_para(init) {} std::string const& to_str() const { return m_para; } bool operator==(Paragraph const& rhs) const { return m_para == rhs.m_para; } bool operator!=(Paragraph const& rhs) const { // Define != operator in terms of the == operator return !(this->operator==(rhs)); } bool operator<(Paragraph const& rhs) const { return m_para < rhs.m_para; } private: friend std::ostream & operator<<(std::ostream &os, const Paragraph& p); std::string m_para; }; std::ostream & operator<<(std::ostream &os, const Paragraph& p) { return os << p.to_str(); } int main() { Paragraph p("Plop"); Paragraph q(p); std::cout << p << std::endl << (p == q) << std::endl; } 

आप इसे सदस्य फंक्शन के रूप में नहीं कर सकते, क्योंकि this पैरामीटर << -operator के बाईं ओर है। (इसलिए, आपको इसे ostream क्लास में सदस्य फ़ंक्शन के रूप में जोड़ना होगा। अच्छा नहीं 🙂

क्या आप इसे बिना किसी friend मुफ्त फ़ंक्शन के रूप में कर सकते हैं? यही मैं जो पसंद करता हूं, क्योंकि यह स्पष्ट करता है कि यह ostream साथ एकीकरण है, और आपकी कक्षा की मुख्य कार्यक्षमता नहीं है।

यदि संभव हो तो गैर-सदस्य और गैर-मित्र कार्य के रूप में

जैसा कि हर्ब सूटर और स्कॉट मेयेर द्वारा वर्णित है, गैर-मित्र गैर-सदस्यीय कार्यों को सदस्य कार्यों में पसंद करते हैं, ताकि इनकैप्सुलेशन में वृद्धि हो सके।

कुछ मामलों में, जैसे सी ++ धाराएं, आपके पास विकल्प नहीं होगा और गैर-सदस्यीय फ़ंक्शंस का उपयोग करना होगा।

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

ऑपरेटर के बारे में << और >> प्रोटोटाइप

मेरा मानना ​​है कि आपके प्रश्न में दिए गए उदाहरण गलत हैं उदाहरण के लिए;

 ostream & operator<<(ostream &os) { return os << paragraph; } 

मैं यह सोच भी नहीं लगा सकता कि यह पद्धति एक धारा में कैसे काम कर सकती है।

<< और >> ऑपरेटर्स को लागू करने के दो तरीके यहां दिए गए हैं

मान लीजिए कि आप टाइप-टी के एक स्ट्रीम-जैसे ऑब्जेक्ट का उपयोग करना चाहते हैं।

और यह कि आप अपने ऑब्जेक्ट प्रकार पैराग्राफ के प्रासंगिक आंकड़े को निकालने / सम्मिलित करना चाहते हैं।

जेनेरिक ऑपरेटर << और >> फ़ंक्शन प्रोटोटाइप

प्रथम कार्य होने के नाते:

 // T << Paragraph T & operator << (T & p_oOutputStream, const Paragraph & p_oParagraph) { // do the insertion of p_oParagraph return p_oOutputStream ; } // T >> Paragraph T & operator >> (T & p_oInputStream, const Paragraph & p_oParagraph) { // do the extraction of p_oParagraph return p_oInputStream ; } 

सामान्य ऑपरेटर << और >> विधि प्रोटोटाइप

दूसरे तरीकों के रूप में हैं:

 // T << Paragraph T & T::operator << (const Paragraph & p_oParagraph) { // do the insertion of p_oParagraph return *this ; } // T >> Paragraph T & T::operator >> (const Paragraph & p_oParagraph) { // do the extraction of p_oParagraph return *this ; } 

नोट करें कि इस नोटेशन का उपयोग करने के लिए, आपको टी के क्लास घोषणापत्र का विस्तार करना होगा। एसटीएल वस्तुओं के लिए, यह संभव नहीं है (आप उन्हें संशोधित नहीं करना चाहते हैं …)।

और क्या होगा अगर टी सी ++ स्ट्रीम है?

यहां समान प्रोटोटाइप हैं << और >> ऑपरेटर सी ++ स्ट्रीम के लिए।

सामान्य मूल_स्ट्रीम और मूल_स्ट्रीम के लिए

ध्यान दें कि धाराओं का मामला है, जैसा कि आप सी ++ स्ट्रीम संशोधित नहीं कर सकते, आपको फ़ंक्शन को कार्यान्वित करना होगा। जिसका अर्थ है कुछ ऐसा:

 // OUTPUT << Paragraph template <typename charT, typename traits> std::basic_ostream<charT,traits> & operator << (std::basic_ostream<charT,traits> & p_oOutputStream, const Paragraph & p_oParagraph) { // do the insertion of p_oParagraph return p_oOutputStream ; } // INPUT >> Paragraph template <typename charT, typename traits> std::basic_istream<charT,traits> & operator >> (std::basic_istream<charT,traits> & p_oInputStream, const CMyObject & p_oParagraph) { // do the extract of p_oParagraph return p_oInputStream ; } 

चार इस्ट्रीम और ओस्ट्रीम के लिए

निम्नलिखित कोड केवल चार-आधारित धाराओं के लिए काम करेगा।

 // OUTPUT << A std::ostream & operator << (std::ostream & p_oOutputStream, const Paragraph & p_oParagraph) { // do the insertion of p_oParagraph return p_oOutputStream ; } // INPUT >> A std::istream & operator >> (std::istream & p_oInputStream, const Paragraph & p_oParagraph) { // do the extract of p_oParagraph return p_oInputStream ; } 

Rhys Ulerich इस तथ्य के बारे में टिप्पणी की है कि चार-आधारित कोड है लेकिन इसके ऊपर सामान्य कोड का "विशेषज्ञता" है बेशक, Rhys सही है: मैं चार-आधारित उदाहरण के उपयोग की अनुशंसा नहीं करता। यह केवल यहां दिया गया है क्योंकि यह पढ़ने में आसान है जैसा कि यह केवल व्यवहार्य है अगर आप केवल चार-आधारित धाराओं के साथ काम करते हैं, तो आपको इसे प्लेटफार्म पर से बचना चाहिए जहां wchar_t कोड सामान्य है (यानी विंडोज़ पर)।

आशा है कि इससे मदद मिलेगी

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

मैंने वास्तव में "ओस्ट्रीमहाल्फर" हेडर और कार्यान्वयन फ़ाइल में इन सभी ओस्ट्रीम आउटपुट फ़्री फ़ंक्शन को इकट्ठा करने के लिए लिया है, यह कक्षाओं के असली उद्देश्य से दूर माध्यमिक कार्यक्षमता रखता है

हस्ताक्षर:

 bool operator<<(const obj&, const obj&); 

बल्कि संदेह नहीं लगता है, यह stream सम्मेलन और न ही बिटवॉश सम्मेलन में फिट नहीं है, इसलिए ऐसा लगता है कि ऑपरेटर ओवरलोडिंग का दुरुपयोग कर रहा है, operator < bool वापस चाहिए, लेकिन operator << शायद कुछ और वापस लौटना चाहिए।

यदि आप ऐसा कहते हैं:

 ostream& operator<<(ostream&, const obj&); 

तब से जब आप आवश्यकता से ostream कार्यों को जोड़ नहीं सकते हैं, तो फ़ंक्शन एक निशुल्क फ़ंक्शन होनी चाहिए, चाहे वह friend या न ही उसका उपयोग करने पर निर्भर करता है (यदि निजी या संरक्षित सदस्यों तक पहुंचने की आवश्यकता नहीं है, तो इसके लिए आवश्यकता नहीं है इसे दोस्त बनाओ)

बस पूरा करने के लिए, मैं जोड़ना चाहूंगा कि आप वास्तव में एक ऑपरेटर ostream& operator << (ostream& os) को एक कक्षा में बना सकते हैं और यह काम कर सकता है मुझे पता है कि इसका उपयोग करने के लिए यह एक अच्छा विचार नहीं है, क्योंकि यह बहुत जटिल और अनूंटिव है

मान लें कि हमारे पास यह कोड है:

 #include <iostream> #include <string> using namespace std; struct Widget { string name; Widget(string _name) : name(_name) {} ostream& operator << (ostream& os) { return os << name; } }; int main() { Widget w1("w1"); Widget w2("w2"); // These two won't work { // Error: operand types are std::ostream << std::ostream // cout << w1.operator<<(cout) << '\n'; // Error: operand types are std::ostream << Widget // cout << w1 << '\n'; } // However these two work { w1 << cout << '\n'; // Call to w1.operator<<(cout) returns a reference to ostream& w2 << w1.operator<<(cout) << '\n'; } return 0; } 

तो यह योग करने के लिए – आप ऐसा कर सकते हैं, लेकिन आपको सबसे ज्यादा संभवतः नहीं होना चाहिए 🙂

operator<< एक दोस्त समारोह के रूप में लागू:

 #include <iostream> #include <string> using namespace std; class Samp { public: int ID; string strName; friend std::ostream& operator<<(std::ostream &os, const Samp& obj); }; std::ostream& operator<<(std::ostream &os, const Samp& obj) { os << obj.ID<< “ ” << obj.strName; return os; } int main() { Samp obj, obj1; obj.ID = 100; obj.strName = "Hello"; obj1=obj; cout << obj <<endl<< obj1; } 

आउटपुट: 100 हैलो 100 हैलो जारी रखने के लिए कोई भी कुंजी दबाएं …

यह एक मित्र समारोह ही हो सकता है क्योंकि ऑब्जेक्ट operator<< के दाहिने हाथ पर है operator<< और तर्क cout बाईं ओर है इसलिए यह कक्षा में कोई सदस्य समारोह नहीं हो सकता है, यह केवल एक दोस्त समारोह हो सकता है

मित्र ऑपरेटर = कक्षा के समान समान अधिकार

 friend std::ostream& operator<<(std::ostream& os, const Object& object) { os << object._atribute1 << " " << object._atribute2 << " " << atribute._atribute3 << std::endl; return os; }