मैं यह नियंत्रित करना चाहूंगा कि coutएक कस्टम क्लास के ऑब्जेक्ट के लिए स्ट्रीम पर क्या लिखा है, अर्थात । क्या यह C ++ में संभव है? जावा में आप toString()इसी तरह के उद्देश्य के लिए विधि को ओवरराइड कर सकते हैं ।
मैं यह नियंत्रित करना चाहूंगा कि coutएक कस्टम क्लास के ऑब्जेक्ट के लिए स्ट्रीम पर क्या लिखा है, अर्थात । क्या यह C ++ में संभव है? जावा में आप toString()इसी तरह के उद्देश्य के लिए विधि को ओवरराइड कर सकते हैं ।
जवाबों:
C ++ में आप और आपके कस्टम वर्ग के operator<<लिए अधिभार कर सकते हैं ostream:
class A {
public:
int i;
};
std::ostream& operator<<(std::ostream &strm, const A &a) {
return strm << "A(" << a.i << ")";
}
इस तरह आप धाराओं पर अपनी कक्षा के उदाहरणों को आउटपुट कर सकते हैं:
A x = ...;
std::cout << x << std::endl;
यदि आप अपनी operator<<कक्षा के आंतरिक भाग का प्रिंट आउट लेना चाहते हैं Aऔर वास्तव में इसके निजी और संरक्षित सदस्यों तक पहुँच की आवश्यकता है, तो आप इसे एक मित्र के रूप में घोषित कर सकते हैं।
class A {
private:
friend std::ostream& operator<<(std::ostream&, const A&);
int j;
};
std::ostream& operator<<(std::ostream &strm, const A &a) {
return strm << "A(" << a.j << ")";
}
friend, और वर्ग के शरीर के अंदर भी - इसके साथ, आपको using namespaceऑपरेटर (और वर्ग) वाले नेमस्पेस के लिए नहीं करना होगा , लेकिन ADL इसे तब तक मिलेगा जब तक कि उस वर्ग की वस्तु नहीं है ऑपरेंड में से एक।
dumpसार्वजनिक तरीका गंदा और अनावश्यक है। friendयहां उपयोग करना पूरी तरह से ठीक है। चाहे आप एक निरर्थक विधि पसंद करते हैं या एक घुसपैठ friendपूरी तरह से स्वाद का मामला है, हालांकि friendइस सटीक उद्देश्य के लिए यकीनन पेश किया गया है।
operator<<()एक सदस्य फ़ंक्शन बनाने से काम नहीं चलेगा: आपको इसके लिए एक सदस्य फ़ंक्शन बनाना होगा ताकि वह std::ostreamबाएं हाथ के प्रकार को स्वीकार कर सके std::ostream।
आप इसे इस तरह भी कर सकते हैं, जिससे बहुरूपता की अनुमति मिलती है:
class Base {
public:
virtual std::ostream& dump(std::ostream& o) const {
return o << "Base: " << b << "; ";
}
private:
int b;
};
class Derived : public Base {
public:
virtual std::ostream& dump(std::ostream& o) const {
return o << "Derived: " << d << "; ";
}
private:
int d;
}
std::ostream& operator<<(std::ostream& o, const Base& b) { return b.dump(o); }
toStringव्यवहार को कॉपी करने के लिए ।
C ++ 11 में, to_string अंत में मानक में जोड़ा जाता है।
http://en.cppreference.com/w/cpp/string/basic_string/to_string
ToString()के आधार वर्ग पर परिभाषित एक आभासी फ़ंक्शन है , और इसलिए इसे किसी भी ऑब्जेक्ट के स्ट्रिंग प्रतिनिधित्व को व्यक्त करने के लिए एक मानक तरीके के रूप में उपयोग किया जाता है। ये फ़ंक्शन केवल अंतर्निहित प्रकारों पर लागू होते हैं। C ++ में मुहावरेदार तरीका कस्टम प्रकारों के लिए ऑपरेटर को ओवरराइड करना है । std::string<<
operator<<सरल Stringशब्दार्थों की तुलना में मानक हस्ताक्षर की "कुरूपता" मुझे टिप्पणी करने के लिए प्रेरित करती है, जो to_string()न केवल "एक उपयोगी जोड़" है, बल्कि सी ++ में इसे करने का नया पसंदीदा तरीका है। यदि, ओपी के अनुसार, एक वर्ग Aका एक कस्टम स्ट्रिंग प्रतिनिधित्व वांछित है, तो बस string to_string(A a)नीचे की परिभाषा लिखना class A। यह जावा में विरासत के रूप में प्रचारित करता है, और जावा में संयुक्त (स्ट्रिंग जोड़कर) हो सकता है। toString()जावा में गैर-ओवरराइडन वैसे भी सीमित उपयोग का है।
जॉन ने जो कहा, उसके विस्तार के रूप में, यदि आप स्ट्रिंग प्रतिनिधित्व को निकालना चाहते हैं और इसे std::stringइस तरह से संग्रहीत करते हैं :
#include <sstream>
// ...
// Suppose a class A
A a;
std::stringstream sstream;
sstream << a;
std::string s = sstream.str(); // or you could use sstream >> s but that would skip out whitespace
std::stringstream<sstream>हैडर में स्थित है ।
सवाल का जवाब दिया गया है। लेकिन मैं एक ठोस उदाहरण जोड़ना चाहता था।
class Point{
public:
Point(int theX, int theY) :x(theX), y(theY)
{}
// Print the object
friend ostream& operator <<(ostream& outputStream, const Point& p);
private:
int x;
int y;
};
ostream& operator <<(ostream& outputStream, const Point& p){
int posX = p.x;
int posY = p.y;
outputStream << "x="<<posX<<","<<"y="<<posY;
return outputStream;
}
इस उदाहरण के लिए ऑपरेटर अधिभार को समझने की आवश्यकता है।