ฉันต้องการควบคุมสิ่งที่เขียนไปยังกระแสข้อมูลเช่น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;
}
ตัวอย่างนี้ต้องการการทำความเข้าใจกับตัวดำเนินการโอเวอร์โหลด