ฉันต้องการควบคุมสิ่งที่เขียนไปยังกระแสข้อมูลเช่นcout
สำหรับวัตถุของคลาสที่กำหนดเอง เป็นไปได้ใน C ++ หรือไม่ ใน Java คุณสามารถแทนที่toString()
วิธีการเพื่อวัตถุประสงค์ที่คล้ายกัน
ฉันต้องการควบคุมสิ่งที่เขียนไปยังกระแสข้อมูลเช่นcout
สำหรับวัตถุของคลาสที่กำหนดเอง เป็นไปได้ใน C ++ หรือไม่ ใน Java คุณสามารถแทนที่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
กับ 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
พฤติกรรมของ Java
ใน C ++ 11, to_string จะถูกเพิ่มเข้าไปในมาตรฐานในที่สุด
http://en.cppreference.com/w/cpp/string/basic_string/to_string
ToString()
เป็นฟังก์ชั่นเสมือนที่กำหนดไว้ในคลาสฐานของวัตถุทั้งหมดและใช้เป็นวิธีมาตรฐานในการแสดงการแทนค่าสตริงของวัตถุใด ๆ ฟังก์ชั่นเหล่านี้std::string
ใช้กับประเภทที่มีอยู่แล้วเท่านั้น วิธีสำนวนใน C ++ คือการแทนที่<<
ผู้ประกอบการสำหรับประเภทที่กำหนดเอง
operator<<
เมื่อเทียบกับซีแมนทิกส์ง่ายๆ String
ของ Java แจ้งให้ฉันสังเกตว่าto_string()
ไม่เพียง แต่ "การเพิ่มที่มีประโยชน์" แต่เป็นวิธีที่นิยมใช้ใน C ++ ถ้าเช่นเดียวกับ OP ต้องการการแทนค่าสตริงแบบกำหนดเองของคลาสA
เพียงแค่เขียนstring to_string(A a)
คำจำกัดความด้านล่างของความclass A
เพียงพอ สิ่งนี้แพร่กระจายด้วยการสืบทอดใน Java และสามารถรวมกัน (โดยการเพิ่มสตริง) เช่นเดียวกับใน Java ไม่ใช่ overriden toString()
ใน Java เป็นของใช้ จำกัด อย่างไรก็ตาม
ในฐานะที่เป็นส่วนขยายของสิ่งที่จอห์นพูดถ้าคุณต้องการแยกการแทนค่าสตริงและเก็บไว้ใน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;
}
ตัวอย่างนี้ต้องการการทำความเข้าใจกับตัวดำเนินการโอเวอร์โหลด