Я хотів би контролювати те, що записується в потік, тобто 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для простору імен, що містять оператора (і класу), але 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 тонінгрінг нарешті додається до стандарту.
http://en.cppreference.com/w/cpp/string/basic_string/to_string
ToString()є віртуальна функція, визначена в базовому класі всіх об'єктів, і тому використовується як стандартний спосіб вираження рядкового подання будь-якого об'єкта. Ці функції стосуються std::stringлише вбудованих типів. Ідіоматичний спосіб у C ++ - це перекриття <<оператора для користувацьких типів.
operator<<порівняно з простою Stringсемантикою Java спонукає мене зауважити, що to_string()це не лише "корисне доповнення", але новий бажаний спосіб зробити це на C ++. Якщо, як це стосується ОП, Aбажане представлення рядка класу на замовлення , просто записуючи string to_string(A a)нижченаведене визначення class Aдостатності. Це поширюється з успадкуванням, як у Java, і може поєднуватися (шляхом додавання рядків), як у Java. Непереборка 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;
}
Цей приклад вимагає розуміння перевантаження оператора.