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 ostream
dan 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 A
dan 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 namespace
untuk namespace yang berisi operator (dan kelas), tetapi ADL akan menemukannya selama objek kelas itu adalah salah satu operan.
dump
metode publik itu kotor dan tidak perlu. Penggunaan di friend
sini baik-baik saja. Apakah Anda lebih suka metode yang berlebihan atau intrusif friend
sepenuhnya adalah masalah selera, meskipun friend
mungkin telah diperkenalkan untuk tujuan yang tepat ini.
operator<<()
fungsi anggota tidak akan berfungsi: Anda harus menjadikannya fungsi anggota std::ostream
agar 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); }
toString
perilaku 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::string
hanya berlaku untuk tipe bawaan. Cara idiomatis dalam C ++ adalah menimpa <<
operator untuk tipe kustom.
operator<<
, dibandingkan dengan String
semantik 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 A
diinginkan, cukup tuliskan string to_string(A a)
definisi class A
suffi 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::string
lakukan 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::stringstream
terletak 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.