जावा के + स्ट्रिंग के बराबर C ++?


151

मैं यह नियंत्रित करना चाहूंगा कि coutएक कस्टम क्लास के ऑब्जेक्ट के लिए स्ट्रीम पर क्या लिखा है, अर्थात । क्या यह C ++ में संभव है? जावा में आप toString()इसी तरह के उद्देश्य के लिए विधि को ओवरराइड कर सकते हैं ।

जवाबों:


176

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 << ")";
}

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

5
बेहतर अभी तक इसे घोषित करें friend, और वर्ग के शरीर के अंदर भी - इसके साथ, आपको using namespaceऑपरेटर (और वर्ग) वाले नेमस्पेस के लिए नहीं करना होगा , लेकिन ADL इसे तब तक मिलेगा जब तक कि उस वर्ग की वस्तु नहीं है ऑपरेंड में से एक।
पावेल मिनेव

... ऊपर कहने का मतलब था " इसे कक्षा के निकाय के अंदर मित्र के रूप में परिभाषित करें " - जैसा कि एक इनलाइन सदस्य परिभाषा है।
पावेल मिनाएव

2
@fnieto: वह dumpसार्वजनिक तरीका गंदा और अनावश्यक है। friendयहां उपयोग करना पूरी तरह से ठीक है। चाहे आप एक निरर्थक विधि पसंद करते हैं या एक घुसपैठ friendपूरी तरह से स्वाद का मामला है, हालांकि friendइस सटीक उद्देश्य के लिए यकीनन पेश किया गया है।
कोनराड रुडोल्फ

1
@Pavel: तर्क पर निर्भर लुकअप वैसे भी मिल जाएगा, जब तक कि ऑपरेटर को क्लास के समान नामस्थान में परिभाषित किया गया है। इसके पास दोस्तों के साथ कुछ भी नहीं है और इसे कक्षा के अंदर घोषित / परिभाषित करने की आवश्यकता नहीं है। इसके अलावा, operator<<()एक सदस्य फ़ंक्शन बनाने से काम नहीं चलेगा: आपको इसके लिए एक सदस्य फ़ंक्शन बनाना होगा ताकि वह std::ostreamबाएं हाथ के प्रकार को स्वीकार कर सके std::ostream
sth

50

आप इसे इस तरह भी कर सकते हैं, जिससे बहुरूपता की अनुमति मिलती है:

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); }

3
वर्चुअल फ़ंक्शन के लिए +1, जावा के toStringव्यवहार को कॉपी करने के लिए ।
कोनराड रुडोल्फ

सीधे ऑपरेटर को निर्दिष्ट करने के बजाय गूंगा क्यों है क्लास में <<?
भिक्षु

1
बीकॉज आप एक अनंत लूप और एक दुर्घटना नहीं करना चाहते हैं
fnieto - फर्नांडो नीटो

1
शायद इस तकनीक को तेजी से और आसानी से पारित होने के विकल्पों पर क्या करना है के लिए आसान है। अन्यथा किसी अन्य क्लास फ्रेंडिंग ऑपरेटर को परिभाषित करना आवश्यक होगा << जो कि विकल्प और डेटा को क्रमबद्ध करने के लिए आरंभीकृत किया गया है।
सैमुअल डेनियलसन

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

29

C ++ 11 में, to_string अंत में मानक में जोड़ा जाता है।

http://en.cppreference.com/w/cpp/string/basic_string/to_string


15
यह इस पृष्ठ के लिए एक उपयोगी जोड़ है, हालांकि जावा / सी # में सी ++ कार्यान्वयन काफी अलग है। उन भाषाओं में, सभी वस्तुओं ToString()के आधार वर्ग पर परिभाषित एक आभासी फ़ंक्शन है , और इसलिए इसे किसी भी ऑब्जेक्ट के स्ट्रिंग प्रतिनिधित्व को व्यक्त करने के लिए एक मानक तरीके के रूप में उपयोग किया जाता है। ये फ़ंक्शन केवल अंतर्निहित प्रकारों पर लागू होते हैं। C ++ में मुहावरेदार तरीका कस्टम प्रकारों के लिए ऑपरेटर को ओवरराइड करना है । std::string<<
ड्रयू नॉक्स

9
जावा के operator<<सरल Stringशब्दार्थों की तुलना में मानक हस्ताक्षर की "कुरूपता" मुझे टिप्पणी करने के लिए प्रेरित करती है, जो to_string()न केवल "एक उपयोगी जोड़" है, बल्कि सी ++ में इसे करने का नया पसंदीदा तरीका है। यदि, ओपी के अनुसार, एक वर्ग Aका एक कस्टम स्ट्रिंग प्रतिनिधित्व वांछित है, तो बस string to_string(A a)नीचे की परिभाषा लिखना class A। यह जावा में विरासत के रूप में प्रचारित करता है, और जावा में संयुक्त (स्ट्रिंग जोड़कर) हो सकता है। toString()जावा में गैर-ओवरराइडन वैसे भी सीमित उपयोग का है।
पी मारेकी

10

जॉन ने जो कहा, उसके विस्तार के रूप में, यदि आप स्ट्रिंग प्रतिनिधित्व को निकालना चाहते हैं और इसे 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>हैडर में स्थित है ।


2
यह एक क्रमिक स्ट्रिंग प्राप्त करने के लिए एक हास्यास्पद बोझिल तरीका है!
गर्ड वैगनर

9

सवाल का जवाब दिया गया है। लेकिन मैं एक ठोस उदाहरण जोड़ना चाहता था।

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;
}

इस उदाहरण के लिए ऑपरेटर अधिभार को समझने की आवश्यकता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.