2010-05-13 19 views
18

एक परियोजना में मैं काम कर रहा हूं, मेरे पास Score वर्ग है, जो score.h में नीचे परिभाषित है। मैं इसे अधिभारित करने की कोशिश कर रहा हूं, जब << ऑपरेशन उस पर किया जाता है, _points + " " + _name मुद्रित होता है।'दोस्त' फ़ंक्शन और << ऑपरेटर ओवरलोडिंग: कक्षा के लिए ऑपरेटर को अधिभारित करने का उचित तरीका क्या है?

ostream & Score::operator<< (ostream & os, Score right) 
{ 
    os << right.getPoints() << " " << right.scoreGetName(); 
    return os; 
} 

यहाँ त्रुटियों लौटे हैं::

score.h(30) : error C2804: binary 'operator <<' has too many parameters 

(यह त्रुटि दिखाई 4 बार, वास्तव में)

मैं यह काम कर रहा करने के लिए प्रबंधित

यहाँ मैं करने की कोशिश की क्या है एक दोस्त समारोह के रूप में ओवरलोड को घोषित करके:

friend ostream & operator<< (ostream & os, Score right); 

और स्कोर.cpp में फ़ंक्शन घोषणा से Score:: को हटा रहा है (प्रभावी रूप से इसे सदस्य के रूप में घोषित नहीं किया गया है)।

यह क्यों काम करता है, फिर भी कोड का पूर्व टुकड़ा नहीं है?

आपके समय के लिए धन्यवाद!

संपादित

मैं नष्ट कर दिया सभी हेडर फाइल पर अधिभार को उल्लेख है ... फिर भी मैं निम्नलिखित (और केवल) त्रुटि मिलती है। binary '<<' : no operator found which takes a right-hand operand of type 'Score' (or there is no acceptable conversion) मेरे परीक्षण, मुख्य() में, कैसे उचित अधिभार नहीं मिल सकता है? (यह भी शामिल है नहीं, मैं जाँच की)

नीचे पूर्ण score.h

#ifndef SCORE_H_ 
#define SCORE_H_ 

#include <string> 
#include <iostream> 
#include <iostream> 

using std::string; 
using std::ostream; 

class Score 
{ 

public: 
    Score(string name); 
    Score(); 
    virtual ~Score(); 
    void addPoints(int n); 
    string scoreGetName() const; 
    int getPoints() const; 
    void scoreSetName(string name); 
    bool operator>(const Score right) const; 

private: 
    string _name; 
    int _points; 

}; 
#endif 

उत्तर

54

नोट है: आप operator overloading FAQ को देखने के लिए चाहते हो सकता है।


बाइनरी ऑपरेटर या तो अपने बाएं हाथ के तर्क वर्ग या मुक्त कार्यों के सदस्य हो सकते हैं। (असाइनमेंट की तरह कुछ ऑपरेटरों को सदस्य होना चाहिए।) चूंकि स्ट्रीम ऑपरेटर के बाएं हाथ का तर्क एक धारा है, इसलिए स्ट्रीम ऑपरेटरों को या तो स्ट्रीम क्लास या फ्री फ़ंक्शंस के सदस्य होना चाहिए। किसी भी प्रकार के operator<< लागू करने के लिए विहित तरीका यह है:

std::ostream& operator<<(std::ostream& os, const T& obj) 
{ 
    // stream obj's data into os 
    return os; 
} 

ध्यान दें कि यह नहीं एक सदस्य कार्य है। यह भी ध्यान रखें कि यह ऑब्जेक्ट प्रति const संदर्भ स्ट्रीम करने के लिए लेता है। ऐसा इसलिए है क्योंकि आप ऑब्जेक्ट को स्ट्रीम करने के लिए कॉपी नहीं करना चाहते हैं और आप नहीं चाहते हैं कि स्ट्रीमिंग इसे बदल दें।


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

inline std::ostream& operator<<(std::ostream& os, const T& obj) 
{ 
    obj.stream_to(os); 
    return os; 
} 

या बनाने के ऑपरेटर एक friend

class T { 
    public: 
    friend std::ostream& operator<<(std::ostream&, const T&); 
    private: 
    int data_; 
}; 
: या तो वर्ग जो स्ट्रीमिंग

class T { 
    public: 
    void stream_to(std::ostream&) const {os << obj.data_;} 
    private: 
    int data_; 
}; 

करता है और ऑपरेटर से फोन है कि में एक सार्वजनिक सदस्य डाल

ताकि वह कक्षा के निजी भागों तक पहुंच सके:

inline std::ostream& operator<<(std::ostream& os, const T& obj) 
{ 
    os << obj.data_; 
    return os; 
} 
+0

अच्छा, पूरा जवाब। –

+0

कक्षा 'निजी भागों - रावर तक पहुंचें। जे/के, बहुत बहुत धन्यवाद, फिर भी एक प्रश्न बनी हुई है: मैंने हेडर फ़ाइल पर अधिभार के सभी उल्लेख हटा दिए हैं ... फिर भी मुझे निम्न (और केवल) त्रुटि मिलती है। 'बाइनरी '<<': कोई ऑपरेटर नहीं मिला जो 'स्कोर' (या कोई स्वीकार्य रूपांतरण नहीं है) का दायां हाथ ऑपरेंड लेता है) मेरा परीक्षण, मुख्य() में कैसे उपयुक्त है, उचित नहीं मिल सकता अधिभार? (इसमें शामिल नहीं है)। –

+1

आपको अपनी कक्षा की परिभाषा के साथ 'ऑपरेटर <<' दाएं घोषित करना चाहिए: वह एक ही शीर्षलेख में और उसी नामस्थान में है। इस तरह आप इसे शामिल करना नहीं भूलेंगे और आप संकलक अधिभार की तलाश करते समय इसे संकलक चुनने में सक्षम होंगे। –

9

मान लीजिए कि आप + के लिए एक ऑपरेटर अधिभार तो आप एक दूसरे के लिए दो Score वस्तुओं जोड़ सकते हैं, और एक अन्य ताकि आप एक Score के लिए एक int जोड़ सकते हैं, और एक तीसरे ताकि आप एक int करने के लिए एक Score जोड़ सकता है लिखना चाहते थे चलो । वे लोग जहां Score पहला पैरामीटर स्कोर के सदस्य कार्य हो सकता है। लेकिन वह एक जहां int पहला पैरामीटर int का सदस्य कार्य नहीं बन सकता है, है ना? इसके साथ आपकी सहायता करने के लिए, आपको उन्हें मुफ्त कार्यों के रूप में लिखने की अनुमति है। यह << ऑपरेटर के साथ क्या हो रहा है, आप ostream पर कोई सदस्य फ़ंक्शन नहीं जोड़ सकते हैं ताकि आप एक नि: शुल्क फ़ंक्शन लिख सकें। जब आप Score:: भाग लेते हैं तो इसका मतलब यह है।

अब यह friend क्यों होना चाहिए? यह नहीं है आप केवल सार्वजनिक तरीकों को बुला रहे हैं (getPoints और scoreGetName)। आप बहुत सारे दोस्त ऑपरेटर देखते हैं क्योंकि वे सीधे निजी चर से बात करना पसंद करते हैं। ऐसा करने के लिए मेरे द्वारा ठीक है, क्योंकि वे वर्ग को बनाए रखने वाले व्यक्ति द्वारा लिखे और बनाए जाते हैं। बस सदस्य-फ़ंक्शन-बनाम-फ्री-फ़ंक्शन भाग के साथ मित्र भाग को गड़बड़ न करें।

+0

धन्यवाद! –

6

आप संकलन त्रुटियों हो रही है जब operator<< उदाहरण में एक सदस्य समारोह है, क्योंकि आप एक operator<< कि पहले पैरामीटर (वस्तु विधि जा रहा है पर कहा जाता है) के रूप में एक Score लेता बना रहे हैं, और फिर इसे एक अतिरिक्त देने अंत में पैरामीटर।

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

A a; 
B b 

a.operator+(b) 

यह आम तौर पर गैर-सदस्य द्विआधारी ऑपरेटरों का उपयोग करने के लिए (और कुछ मामलों में प्राथमिकता दी जाती है - जैसे ostream के लिए operator<< यह करने के लिए एक ही रास्ता है उस मामले में, a + b की तरह काम कर सकते हैं। इस:

A a; 
B b 

operator+(a, b); 

यहाँ एक पूर्ण कर के दोनों तरीकों से दिखा उदाहरण है; main() होगा उत्पादन '55' तीन बार:

#include <iostream> 

struct B 
{ 
    B(int b) : value(b) {} 
    int value; 
}; 


struct A 
{ 
    A(int a) : value(a) {} 
    int value; 

    int operator+(const B& b) 
    { 
     return this->value + b.value; 
    } 
}; 

int operator+(const A& a, const B& b) 
{ 
    return a.value + b.value; 
} 

int main(int argc, char** argv) 
{ 
    A a(22); 
    B b(33); 

    std::cout << a + b << std::endl; 
    std::cout << operator+(a, b) << std::endl; 
    std::cout << a.operator+(b) << std::endl; 

    return 0; 
} 
संबंधित मुद्दे