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 ostreamve ö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 Ave 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 namespaceiş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.
dumpgenel yöntem kirli ve gereksizdir. friendBurada kullanmak gayet iyi. Gereksiz bir yöntem veya müdahaleci tercih edip etmemek friendtamamen bir zevk meselesidir, ancak friendbu kesin amaç için tartışmalı olarak getirilmiştir.
operator<<()üye işlevi yapmak işe yaramaz: std::ostreamsol 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); }
toStringdavranışı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 Stringanlambilimine 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 Aisteniyorsa, sadece string to_string(A a)aşağıdaki class Ayeterliliklerin 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::stringstreambulunan <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.