Saya ingin mengontrol apa yang ditulis ke aliran, yaitu cout, untuk objek kelas kustom. Apakah itu mungkin di C ++? Di Jawa Anda bisa mengganti toString()metode untuk tujuan yang sama.
Saya ingin mengontrol apa yang ditulis ke aliran, yaitu cout, untuk objek kelas kustom. Apakah itu mungkin di C ++? Di Jawa Anda bisa mengganti toString()metode untuk tujuan yang sama.
Jawaban:
Di C ++ Anda dapat kelebihan operator<<untuk ostreamdan kelas khusus Anda:
class A {
public:
int i;
};
std::ostream& operator<<(std::ostream &strm, const A &a) {
return strm << "A(" << a.i << ")";
}
Dengan cara ini Anda dapat menampilkan instance kelas Anda di stream:
A x = ...;
std::cout << x << std::endl;
Jika Anda operator<<ingin mencetak internal kelas Adan benar-benar membutuhkan akses ke anggota pribadi dan terlindungi, Anda juga dapat mendeklarasikannya sebagai fungsi teman:
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, dan juga di dalam tubuh kelas - dengan itu, Anda tidak harus melakukan using namespaceuntuk namespace yang berisi operator (dan kelas), tetapi ADL akan menemukannya selama objek kelas itu adalah salah satu operan.
dumpmetode publik itu kotor dan tidak perlu. Penggunaan di friendsini baik-baik saja. Apakah Anda lebih suka metode yang berlebihan atau intrusif friendsepenuhnya adalah masalah selera, meskipun friendmungkin telah diperkenalkan untuk tujuan yang tepat ini.
operator<<()fungsi anggota tidak akan berfungsi: Anda harus menjadikannya fungsi anggota std::ostreamagar dapat menerima operan tipe tangan kiri std::ostream.
Anda juga dapat melakukannya dengan cara ini, memungkinkan polimorfisme:
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); }
toStringperilaku Java .
Dalam C ++ 11, to_string akhirnya ditambahkan ke standar.
http://en.cppreference.com/w/cpp/string/basic_string/to_string
ToString()adalah fungsi virtual yang didefinisikan pada kelas dasar dari semua objek, dan karenanya digunakan sebagai cara standar untuk mengekspresikan representasi string dari objek apa pun. Fungsi-fungsi ini std::stringhanya berlaku untuk tipe bawaan. Cara idiomatis dalam C ++ adalah menimpa <<operator untuk tipe kustom.
operator<<, dibandingkan dengan Stringsemantik sederhana Jawa mendorong saya untuk berkomentar, itu to_string()bukan hanya "tambahan yang berguna", tetapi cara baru yang disukai untuk melakukannya di C ++. Jika, seperti oleh OP, representasi string kustom dari sebuah kelas Adiinginkan, cukup tuliskan string to_string(A a)definisi class Asuffi di bawah ini . Ini menyebar dengan pewarisan seperti di Jawa, dan dapat dikombinasikan (dengan penambahan string) seperti di Jawa. Lagipula Non-override toString()di Jawa penggunaannya terbatas.
Sebagai perpanjangan dari apa yang dikatakan John, jika Anda ingin mengekstraksi representasi string dan menyimpannya di std::stringlakukan ini:
#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::stringstreamterletak di <sstream>tajuk.
Pertanyaan telah dijawab Tetapi saya ingin menambahkan contoh konkret.
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;
}
Contoh ini membutuhkan pemahaman operator yang berlebihan.