M
Michael
I have a solution for this, but it feels wrong. If anyone could offer
a better one, I'm all ears. (Or technically, eyes.)
Basically, I have a bunch of classes. For concreteness, one is a
Matrix class, but that's only one example, so please don't get too hung
up on it.
I need to output and input these classes. I'd like a nice, pretty,
human readable output, something like:
1 2 3
4 5 6
(note spaces and new lines).
For speed purposes (and yes, I have measured this, and yes, it does
make a difference), I also want a compressed binary version, which
would look like this:
<rows><columns><num>*
(note: no delimiters, you get all the info from the rows and columns).
I definitely need to read and write the binary version, but for some
classes I don't need to read the human readable version.
So what I have looks like this:
/// Output in textual format
std:stream& operator<<(std:stream& os, const Matrix& m);
/// Output in binary format
BinaryOStream& operator<<(BinaryOStream& os, const Matrix& m);
where BinaryOStream is defined like this:
class BinaryOStream
{
public:
/** The underlying ofstream wrapped by this class. */
std:fstream m_out;
public:
/// Create a BinaryOStream from a given filename.
BinaryOStream(const std::string& filename);
~BinaryOStream(void){}
//etc
}
and its constructor opens m_out in binary mode. It also has a series
of non-member << operators for different data types (some of which are
implemented as a template).
What I don't like about the current solution is that I wind up writing
what feels like twice as much code as I should have to. Especially if
I need to read in the format (and Matrix is a bad example for this), it
seems like for most of my classes, the same input should work for both
(imagine another class where the outputs are the same except that the
text has spaces and newlines - I won't cut and paste the code here, but
you get the idea).
I kind of feel like BinaryOStream should inherit from ostream, and
implement the decorator pattern; that way I'd just write stuff for
ostream, and overload for BinaryOStream if I need to, but I can't quite
figure out how to make that work. (In particular, I would love to be
able to output stuff to a 'binary ostringstream' for testing purposes,
instead of to an actual file.)
Has anyone done this sort of thing before, and if so, found a clean
solution?
Michael
a better one, I'm all ears. (Or technically, eyes.)
Basically, I have a bunch of classes. For concreteness, one is a
Matrix class, but that's only one example, so please don't get too hung
up on it.
I need to output and input these classes. I'd like a nice, pretty,
human readable output, something like:
1 2 3
4 5 6
(note spaces and new lines).
For speed purposes (and yes, I have measured this, and yes, it does
make a difference), I also want a compressed binary version, which
would look like this:
<rows><columns><num>*
(note: no delimiters, you get all the info from the rows and columns).
I definitely need to read and write the binary version, but for some
classes I don't need to read the human readable version.
So what I have looks like this:
/// Output in textual format
std:stream& operator<<(std:stream& os, const Matrix& m);
/// Output in binary format
BinaryOStream& operator<<(BinaryOStream& os, const Matrix& m);
where BinaryOStream is defined like this:
class BinaryOStream
{
public:
/** The underlying ofstream wrapped by this class. */
std:fstream m_out;
public:
/// Create a BinaryOStream from a given filename.
BinaryOStream(const std::string& filename);
~BinaryOStream(void){}
//etc
}
and its constructor opens m_out in binary mode. It also has a series
of non-member << operators for different data types (some of which are
implemented as a template).
What I don't like about the current solution is that I wind up writing
what feels like twice as much code as I should have to. Especially if
I need to read in the format (and Matrix is a bad example for this), it
seems like for most of my classes, the same input should work for both
(imagine another class where the outputs are the same except that the
text has spaces and newlines - I won't cut and paste the code here, but
you get the idea).
I kind of feel like BinaryOStream should inherit from ostream, and
implement the decorator pattern; that way I'd just write stuff for
ostream, and overload for BinaryOStream if I need to, but I can't quite
figure out how to make that work. (In particular, I would love to be
able to output stuff to a 'binary ostringstream' for testing purposes,
instead of to an actual file.)
Has anyone done this sort of thing before, and if so, found a clean
solution?
Michael