2010-12-31 45 views
36

मुझे वर्चुअल < < ऑपरेटर का उपयोग करने की आवश्यकता है। हालांकि, जब मैं लिखने की कोशिश: 'ऑपरेटर < <':ऑपरेटर बनाना << आभासी?

virtual friend ostream & operator<<(ostream& os,const Advertising& add); 

मैं संकलक त्रुटि

त्रुटि 1 त्रुटि C2575 मिल केवल सदस्य कार्य करता है और ठिकानों हो सकता है आभासी

मैं इस ऑपरेटर वर्चुअल को कैसे बदल सकता हूं?

उत्तर

63

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

class MyClass { 
public: 
    virtual ostream& operator<< (ostream& out) const; 
}; 

मतलब यह है कि

MyClass myObject; 
cout << myObject; 

संकलन नहीं होगा, लेकिन

MyClass myObject; 
myObject << cout; 

कानूनी हो जाएगा।

इसे ठीक करने के लिए, आप सॉफ्टवेयर इंजीनियरिंग के मौलिक प्रमेय को लागू कर सकते हैं - किसी भी समस्या को संकेत की एक और परत जोड़कर हल किया जा सकता है।

ostream& operator<< (ostream& out, const MyClass& mc) { 
    mc.print(out); 
    return out; 
} 

के रूप में फिर

class MyClass { 
public: 
    virtual void print(ostream& where) const; 
}; 

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

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

+0

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

+4

* "किसी भी समस्या को संकेत की एक और परत जोड़कर हल किया जा सकता है" * - याद रखें, संकेत की बहुत सारी परतों की समस्या को छोड़कर कोई समस्या;) – Kos

+12

@ कोस: नहीं, नहीं। जब तक आपने इसे 'हस्ताक्षरित अप्रत्यक्षता घोषित कर दिया हो;', आपको केवल अधिक से अधिक संकेत जोड़ने को जोड़ना होगा और जब आप –

2

ऐसा लगता है कि आप वास्तव में कक्षाओं के पदानुक्रम के लिए आउटपुट कार्यक्षमता प्रदान करना चाहते हैं, और यदि ऐसा है, तो आप friend operator << प्रदान कर सकते हैं जो virtual फ़ंक्शन को कॉल करता है।

class Parent 
{ 
public: 
    friend std::ostream& operator<< (std::ostream& os, const Parent& p); 
    // ... other class stuff 
protected: 
    virtual void printMyself(std::ostream& os) const 
    { 
     // do something if you must, or make this a pure virtual 
    } 
}; 

std::ostream& operator<< (std::ostream& os, const Parent& p) 
{ 
    p.printMyself(os); 
    return os; 
} 

class Child : public Parent 
{ 
    // other class stuff... 
protected: 
    virtual void printMyself(std::ostream os) const 
    { 
     // whatever you need to do 
    } 
}; 

इसके अलावा C++ FAQ

25

में विस्तृत तुम एक आभासी प्रिंट विधि कॉल करने के अपने ऑपरेटर < < को परिभाषित:

class Base 
{ 
    protected: 
     virtual void print(std::ostream& str) const = 0; 
    public: 
     friend std::ostream& operator<<(std::ostream& str, Base const& data) 
     { 
      data.print(str); 
      return str; 
     } 
} 
+1

पर रोल करते हैं तो समस्या स्वयं हल हो जाएगी, संभवत: 'data.print (str); ' –

+0

इसके अतिरिक्त @ जीन की टिप्पणी के लिए, शुद्ध वर्चुअल फ़ंक्शन को संरक्षित करने की आवश्यकता है ताकि गैर-मित्र व्युत्पन्न कक्षाएं इसे कार्यान्वित कर सकें। –

+1

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

-2

तकनीक का उपयोग मैं कि कार्यात्मक दूसरों क्या उल्लेख किया है के समान है, सिवाय इसके कि मैं वर्चुअल "प्रिंट" फ़ंक्शन को >> ऑपरेटर का सदस्य फ़ंक्शन अधिभार बना देता हूं:

class my_class 
{ 
protected: 
    virtual std::ostream& operator>>(std::ostream& os_) const 
    { 
     // print *this to `os_` 
     return os_; 
    } 

public: 
    friend inline std::ostream& operator<<(std::ostream& os, const my_class& mc) { 
     return (mc >> os); 
    } 
}; 

यह मेरी ओपन सोर्स प्रोजेक्ट्स में से एक से उपयोगिता टेम्पलेट के पीछे विचार है। देखें: https://libnstdcxx.googlecode.com/svn/trunk/doc/html/classnstd_1_1basic__printable.html

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