Java의 toString과 동등한 C ++?


151

스트림에 쓰여지는 내용, 즉 cout사용자 정의 클래스의 객체 를 제어하고 싶습니다 . C ++에서 가능합니까? Java에서는 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
클래스의 private 멤버에 액세스해야 할 수도 있으므로 operator <<를 클래스의 friend 함수로 선언하는 것이 좋습니다.
Naveen

5
더 잘 선언 friend하고 클래스 본문 안에 선언하십시오 - using namespace연산자와 클래스가 포함 된 네임 스페이스 를 수행 할 필요는 없지만 ADL은 해당 클래스의 객체가있는 한 그것을 찾습니다. 피연산자 중 하나입니다.
Pavel Minaev

... 위의 내용은 인라인 멤버 정의에서와 같이 "클래스의 본문 내에서 친구로 정의 "라고 말하기위한 것 입니다.
Pavel Minaev

2
@ fnieto : 그 dump공개 방법은 더럽고 불필요합니다. friend여기서 사용하는 것은 완벽합니다. 중복 된 방법을 선호하든 침입 성을 선호하는지 friend는 전적으로 맛의 문제입니다 friend.
Konrad Rudolph

1
@Pavel : 연산자가 클래스와 동일한 네임 스페이스에 정의되어있는 한 인수 의존적 조회는 어쨌든 찾을 것입니다. 이것은 친구들과 아무 관련이 없으며 클래스 내에서 선언 / 정의 할 필요가 없습니다. 또한 operator<<()멤버 함수를 만드는 것은 효과가 없습니다. std::ostream왼쪽 피연산자를 type 의 멤버 함수 로 받아들이려면 멤버 함수로 만들어야합니다 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
Java의 toString동작 을 복사하기 위해 가상 기능의 경우 +1
Konrad Rudolph

왜 클래스에서 operator <<를 직접 지정하지 않고 바보입니까?
monksy

1
beacause 당신은 무한 루프와 충돌하고 싶지 않아
fnieto-페르난도 니에 토

1
아마도이 기술은 직렬화 할 항목에 대한 옵션을 전달하는 데 빠르고 쉽습니다. 그렇지 않으면 옵션과 직렬화 할 데이터로 초기화 된 다른 클래스 친구 연산자 <<를 정의해야합니다.
사무엘 다니엘 슨

또 다른 요점은 덤프 기능의 구현이 인터페이스에 의해 시행 될 수 있으며 제안 된 연산자로는 불가능할 수 있다는 것입니다.
jupp0r

29

C ++ 11에서는 to_string이 표준에 추가되었습니다.

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


15
이것은이 페이지에 유용한 추가 사항이지만 C ++ 구현은 Java / C #의 구현과 크게 다릅니다. 이러한 언어에서 모든 객체 ToString()의 기본 클래스에 정의 된 가상 함수 이므로 모든 객체의 문자열 표현을 표현하는 표준 방법으로 사용됩니다. 이 기능은 std::string내장 유형에만 적용됩니다. C ++의 관용적 인 방법은 <<사용자 정의 유형 의 연산자 를 재정의하는 것 입니다.
Drew Noakes

9
Java의 operator<<간단한 String의미 와 비교할 때 표준 시그니처의 "추악함"은 to_string()"유용한 추가 사항"일뿐만 아니라 C ++에서이를 선호하는 새로운 기본 방법입니다. OP에 의해 클래스의 사용자 정의 문자열 표현 A이 필요한 경우 string to_string(A a)아래의 class A충분 정의를 작성하십시오 . 이것은 Java에서와 같이 상속으로 전파되며 Java에서와 같이 (문자열 추가로) 결합 될 수 있습니다. toString()Java에서 오버라이드되지 않은 것은 어쨌든 제한적으로 사용됩니다.
P Marecki

10

John이 말한 것의 확장으로 문자열 표현을 추출하여 저장하려면 다음과 같이 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
직렬화 문자열을 얻는 것이 어리석은 번거로운 방법입니다!
Gerd Wagner

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

이 예제에서는 운영자 과부하를 이해해야합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.