Bir akışa yazılanları, yani cout
özel bir sınıftaki bir nesneyi kontrol etmek istiyorum . Bu C ++ ile mümkün mü? Java'da toString()
benzer amaçlarla yöntemi geçersiz kılabilirsiniz .
Bir akışa yazılanları, yani cout
özel bir sınıftaki bir nesneyi kontrol etmek istiyorum . Bu C ++ ile mümkün mü? Java'da toString()
benzer amaçlarla yöntemi geçersiz kılabilirsiniz .
Yanıtlar:
C ++ sen aşırı olabilir operator<<
için ostream
ve özel sınıfı:
class A {
public:
int i;
};
std::ostream& operator<<(std::ostream &strm, const A &a) {
return strm << "A(" << a.i << ")";
}
Bu şekilde sınıfınızın örneklerini akışlara gönderebilirsiniz:
A x = ...;
std::cout << x << std::endl;
Durumda senin operator<<
istekler sınıfın iç görün yazdırmak A
ve gerçekten de arkadaş fonksiyonu olarak ilan verebilir, özel ve korumalı üyeler erişmesi gerekir:
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
, onu sınıfın gövdesi içinde ve aynı zamanda - using namespace
işleci (ve sınıfı) içeren ad alanı için yapmak zorunda kalmayacaksınız, ancak ADL bunu sınıfın nesnesi olduğu sürece bulacaktır. işlenenlerden biri.
dump
genel yöntem kirli ve gereksizdir. friend
Burada kullanmak gayet iyi. Gereksiz bir yöntem veya müdahaleci tercih edip etmemek friend
tamamen bir zevk meselesidir, ancak friend
bu kesin amaç için tartışmalı olarak getirilmiştir.
operator<<()
üye işlevi yapmak işe yaramaz: std::ostream
sol tür işleneni kabul etmesi için onu üye işlevi yapmak zorunda kalırsınız std::ostream
.
Ayrıca, polimorfizme izin vererek bu şekilde de yapabilirsiniz:
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
davranışını kopyalamak için sanal işlev için +1 .
C ++ 11'de, nihayet standarda to_string eklenir.
http://en.cppreference.com/w/cpp/string/basic_string/to_string
ToString()
temel sınıfında tanımlanan sanal bir işlevdir ve bu nedenle herhangi bir nesnenin dize olarak temsilini ifade etmek için standart bir yol olarak kullanılır. Bu işlevler yalnızca yerleşik türler için geçerlidir. C ++ içindeki deyimsel yol, özel türler için işleci geçersiz kılmaktır. std::string
<<
operator<<
basit String
anlambilimine kıyasla standart imzanın "çirkinliği", to_string()
sadece "yararlı bir ekleme" değil, C ++ 'da bunu yapmanın tercih edilen yeni yoludur. OP tarafından olduğu gibi, bir sınıfın özel bir dize temsili A
isteniyorsa, sadece string to_string(A a)
aşağıdaki class A
yeterliliklerin tanımını yazmak gerekir . Bu, Java'daki gibi kalıtımla yayılır ve Java'daki gibi birleştirilebilir (dize ekleyerek). toString()
Java'da geçersiz kılmamak zaten sınırlıdır.
John'un söylediklerinin bir uzantısı olarak, dize temsilini çıkarmak ve bunu bir saklamak istiyorsanız 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
bulunan <sstream>
başlığı.
Soru cevaplandı. Ama somut bir örnek eklemek istedim.
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;
}
Bu örnekte operatörün aşırı yüklenmesi anlaşılmalıdır.