Я хотел бы контролировать то, что записывается в поток, т. Е. cout
Для объекта пользовательского класса. Это возможно в C ++? В Java вы можете переопределить toString()
метод для аналогичной цели.
151
В 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
.Вы также можете сделать это таким образом, разрешив полиморфизм:
источник
toString
поведение Java .В C ++ 11 to_string наконец добавляется в стандарт.
http://en.cppreference.com/w/cpp/string/basic_string/to_string
источник
ToString()
это виртуальная функция, определенная в базовом классе всех объектов, и поэтому она используется как стандартный способ выражения строкового представления любого объекта. Эти функцииstd::string
относятся только к встроенным типам. Идиоматический способ в C ++ - переопределить<<
оператор для пользовательских типов.operator<<
сравнению с простойString
семантикой Java заставляет меня заметить, чтоto_string()
это не только «полезное дополнение», но и новый предпочтительный способ сделать это в C ++. Если, как и в случае с OP,A
желательно пользовательское строковое представление класса , достаточно просто написать приведенноеstring to_string(A a)
ниже определениеclass A
. Это распространяется с наследованием, как в Java, и может быть объединено (путем добавления строки), как в Java. Не переопределенныйtoString()
в Java в любом случае имеет ограниченное использование.В качестве дополнения к тому, что сказал Джон, если вы хотите извлечь строковое представление и сохранить его в
std::string
:std::stringstream
находится в<sstream>
шапке.источник
На вопрос был дан ответ. Но я хотел бы добавить конкретный пример.
Этот пример требует понимания перегрузки оператора.
источник