我使用
cout
或 ofstream
输出我的类对象。我知道插入运算符 <<
是将对象转换为字符串或打印它的标准方法。我想在项目的不同部分使用不同的格式。
我希望该类有许多不同的字符串格式。然而,该类只能有一个插入运算符。
在C++中解决这个问题的常用方法有哪些?
我使用的一个解决方案是让多个函数返回字符串。我的理解是,重载插入运算符是输出对象的最常见方法,我希望有这种解决方案。
使用不同的格式听起来像是策略模式。我想模板也是解决很多问题的强大工具。我对这两种解决方案都不熟悉。
这是一个演示该问题的代码示例:
#include <iostream>
#include <sstream>
class Point {
public:
Point(int x, int y): x(x), y(y) {}
std::string to_string() {
std::ostringstream stream;
stream << "(" << x << ", " << y << ")";
return stream.str();
}
friend std::ostream& operator<<(std::ostream& out, const Point& p) {
return out << p.x << " " << p.y;
}
private:
int x, y;
};
int main() {
Point p { 4, 2 };
std::cout << p << std::endl;
std::cout << p.to_string() << std::endl;
}
我想摆脱
to_string
函数并使用插入运算符来获取所有格式。定义插入操作符使用哪种格式的简单方法是什么?应该可以改变对象的格式。
课程可能有两种以上不同的形式。
您可以为此任务定义自己的 I/O 流操纵器,类似于字符串的
std::quoted
。
例如:
#include <iostream>
class Point {
public:
Point(int x, int y): x(x), y(y) {}
private:
int x, y;
friend struct s_Point_printer;
};
struct s_Point_printer {
const Point &m_pt;
const bool m_parenthesis;
s_Point_printer(const Point &pt, bool parenthesis) : m_pt(pt), m_parenthesis(parenthesis) {}
void printTo(std::ostream &out) const {
if (m_parenthesis)
out << "(" << m_pt.x << ", " << m_pt.y << ")";
else
out << m_pt.x << " " << m_pt.y;
}
friend std::ostream& operator<<(std::ostream &out, const s_Point_printer &printer) {
printer.printTo(out);
return out;
}
};
s_Point_printer with_parens( const Point& pt ) {
return s_Point_printer{pt, true};
}
s_Point_printer without_parens( const Point& pt ) {
return s_Point_printer{pt, false};
}
int main() {
Point p { 4, 2 };
std::cout << without_parens(p) << std::endl; // prints "4 2"
std::cout << with_parens(p) << std::endl; // prints "(4, 2)"
}
或者:
class Point {
public:
static int point_xalloc;
Point(int x, int y): x(x), y(y) {}
friend std::ostream& operator<<(std::ostream& os, const Point& pt) {
if (os.iword(Point::point_xalloc) == 1)
return os << "(" << pt.x << ", " << pt.y << ")";
else
return os << pt.x << " " << pt.y;
}
private:
int x, y;
};
int Point::point_xalloc = std::ios_base::xalloc();
std::ios_base& with_parens(std::ios_base& os) {
os.iword(Point::point_xalloc) = 1;
return os;
}
std::ios_base& without_parens(std::ios_base& os) {
os.iword(Point::point_xalloc) = 0;
return os;
}
int main() {
Point p { 4, 2 };
std::cout << without_parens << p << std::endl; // prints "4 2"
std::cout << with_parens << p << std::endl; // prints "(4, 2)"
}