Overloading << for both iostream and fstream - c++

I am trying to overload both cout from iostream and fout from fstream
ostream& operator<<(ostream& cout, const Object& obj);
ofstream& operator<<(ofstream& fout, const Object& obj);
I want the first function to work with the console so have text for the user while I want the second function to only output the value of the variables onto a file.
However, in
void save_data(const Object& obj)
{
fstream fout("DataBase.txt", ios::out);
if (fout.is_open())
{
fout << obj;
fout.close();
}
else
cout << "DataBase.txt could not be saved!" << endl;
}
I have text that I used to guide the user inside my function that overloads cout in my file.

std::fstream inherits from std::iostream, which in turn inherits from std::ostream. There's no std::ofstream in that chain, making that overload an unsuitable candidate.
One way to fix this is to use std::ofstream at the callsite instead of std::fstream. You can also add an overload for std::fstream. However, be aware that std::ostream is not necessarily the console; that's a guarantee you have to provide yourself from the rest of the code. For example, a std::ofstream could be upcast to std::ostream and then used to print an Object and your overload set would assume this stream is for the console. It might be hard to ensure the rest of your code provides that guarantee. In addition, robust detection of a console is going to be platform-dependent with its own answers elsewhere on the site (e.g., for Windows).
One way that existing programs handle this requirement is to have an explicit "interactive" option on the command line. For example, git commands use --interactive and sometimes -i for this purpose. This way, the user asks for the extra guiding output and there's no clever detection trickery required.

Thanks to the help from #chris I was able to figure out what the real problem was. Normally one doesn't need to overload based on the base and derived I/O stream types. There's usually a polymorphic way to do what you want. In this case you can check if the stream being written to is std::cout and construct a new stream with a buffer to write to it.
std::ostream& operator<<(std::ostream& os, Obj const& obj) {
std::ostream o(nullptr);
if (&os == &std::cout) {
o.rdbuf(std::cout.rdbuf());
}
o << "hello\n";
return os;
}
Writing to o will do nothing if the buffer is a null pointer. This will allow you to write your console output guides for the user without separating both implementations.
If you would still like to split the implementations, create two functions and call the appropriate one when the above if condition is true and false.
std::ostream& write_with_console_o(std::ostream&);
std::ostream& write_with_file_o(std::ostream&);
std::ostream& operator<<(std::ostream& os, Obj const& obj) {
if (&os == &std::cout) {
return write_with_console_o(os);
}
return write_with_file_o(os);
}

Related

Buffer flushing in ostream overloading

What is the recommended way to use buffer flushing when overloading ostream in C++? Do I just disable buffer flushing in the beginning and enable it in the end? If so should i flush the buffer before returning the ostream? I have never seen this part mentioned in any ostream overloading reference.
EDIT: Lets say i have a class with a lot of members. The ostream operator prints each member. How should i write the ostream overload?
struct ToPrint {
char firstMember;
char secondMember;
int number;
};
std::ostream& operator<<(std::ostream& os, const ToPrint& instance) {
os << instance.firstMember << '\n'
<< instance.secondMember << '\n';
if (instance.number > 0)
os << instance.number << '\n';
return os;
}
The recommended use of buffer flushing for output streams in C++ is to not do it. Unless you have special requirements, the default behavior of the stream will work just fine.

C++ Best approach to filtering bytes in a stream

I'm learning c++ (coming from a C and Java university coursework) and today I want to write a class that filters the bytes taken from a generic stream and writes its output to another stream.
To be coincise, let's say I want to make a class that base64-encodes the input and writes the output to stdout.
In bash I would write:
echo "some input data" | base64
In C++ i want to implement a class MyB64Encoder that would behave like this:
std::cout << myB64EncoderObject << "some input data";
//Alternatively, is it possible to make it like this?
std::cout << MyB64Encoder << "some input data";
The thing is, the myB64EncoderObject has, of course, to maintain an internal state and an internal buffer. To prevent blocking and excessive memory usage, it must be able to read and process small chunks of data and output each one of them immediately after it has been processed.
There are a few more things to take care of:
The object must wait for the output stream to be able to receive data
The object must throw an error if there is no stream reading from it (kinda like a broken pipe?)
What would be the best approach to a problem like this, in terms of efficiency? How would I implement it in modern C++1x?
The existing things that behave like this:
std::cout << myB64EncoderObject << "some input data";
are I/O manipulators (eg. std::boolalpha, std::hex, ...). However, these just set flags on the stream that it already knows how to interpret.
If you want to keep that syntax, you'll need to something more complex, namely an intermediate wrapper:
class B64Wrapper {
std::ostream &os_;
B64Encoder &enc_; // only if your encoder is really stateful
public:
B64Wrapper() = delete;
B64Wrapper(B64Wrapper&&) = default;
B64Wrapper(B64Wrapper const&) = default;
B64Wrapper(std::ostream &os, B64Encoder &enc) : os_(os), enc_(enc) {}
template <typename T>
B64Wrapper& operator<< (B64Wrapper &self, T val) {
self.enc_.encode(os_, val);
return self;
}
};
B64Wrapper operator<< (std::ostream &os, B64Encoder &enc) {
return B64Wrapper(os, enc);
}
(note you still need to write the B64Encoder::encode(std::ostream &, T value) method).
If your encoder isn't really stateful, you don't need a reference to it, and declare B64Encoder as an empty tag type with a global instance to get the same effect - in that case it only exists to select the operator<< overload.
The other approach is to write a std::basic_streambuf implementation which encodes the input to sputc/sputn/xsputn. It can forward everything else to a wrapped streambuf or to the base class, depending on what you inherit from.
You can do something like this:
class MyEncoder
{
public:
private:
std::ostream* os = nullptr;
// This overload deals with:
// std::cout << myEncoder ...
friend MyEncoder& operator<<(std::ostream& os, MyEncoder& me)
{
// grab a reference to the target output stream
me.os = &os;
return me;
}
// This overload deals with:
// std::cout << MyEncoder() ...
friend MyEncoder& operator<<(std::ostream& os, MyEncoder&& me)
{
// the temporary is currently bound to the l-value parameter me
// so we can just pass this call on to the previous overload
return os << me;
}
// This overload deals with:
// myEncoder << <anything else>
template<typename T>
friend MyEncoder& operator<<(MyEncoder& me, T const& v)
{
// only encode if there is an output stream to send the data to
// this will only be set if one of the above overloads was called
if(!me.os)
throw std::runtime_error("no stream to receive encoded data");
// do your encoding here
(*me.os) << "{encoded: " << v << "}";
return me;
}
};
Basically to achieve this:
std::cout << MyEncoder() << "some data: " << 45;
// ^ calls operator<<(MyEncoder&, 45)
// ^ calls operator<<(MyEncoder&, "some data: ")
// ^ calls operator<<(std::cout, MyEncoder())
The calls go left to right.
It may seem a little involved but it is basically covering 3 different call possibilities.
MyEncoder encoder;
std::cout << encoder; // MyEncoder& object
std::cout << MyEncoder(); // (temporary) MyEncoder&& object
encoder << "anything else" // A MyEncoder& receiving any other object
The first 2 operators are overloaded to set the internal std::ostream* and the third operator is overloaded to do the actual encoding.

what's the best practice to print out(print debugging information) for a class?

I am wondering what's the best practice to print out a class (say classA), I have several method
classA ca;
1) Define a debug method and inside this method , print out all its members.
2) Define a str() method, and use cout<< ca.str()
3) Define something like string conversion(I am not sure how yet), and just use cout << ca
The usual way is to overload operator<< roughly like this:
std::ostream &operator<<(std::ostream &out, classA const &a) {
// precise formatting depends on your use case. Do the same thing you would
// if you wanted to print a to cout or a file, because that is what this code
// will end up doing.
out << a.some_data() << ", " << a.some_more_data();
return out;
}
If classA has a limited interface (does not expose all relevant data members), it may be necessary to make the operator<< a friend of classA, such as
class A {
public:
// stuff
friend operator<<(std::ostream &out, classA const &a);
};
// private members can then be accessed
std::ostream &operator<<(std::ostream &out, classA const &a) {
out << a.some_private_member << ", " << a.some_other_private_member;
return out;
}
There is not usually a good reason to prevent read access to private members that you then enable the user to dump out per operator<<, though, since it would be rather leaky access control.
This then enables you to write
classA a;
std::cout << a;
std::ofstream file("foo.txt");
file << a;
std::ostringstream fmt;
fmt << a;
std::string s = fmt.str();
and so forth.
As a style note: It is possible to write
std::ostream &operator<<(std::ostream &out, classA const &a) {
// precise formatting depends on your use case
return out << a.some_data() << ", " << a.some_more_data();
}
This achieves the same thing as the split return because operator<< (by convention) returns the same stream object that was passed into it (to enable the chaining of << as in std::cout << i << j << k;).
Style note 2: If there is nothing in classA that makes it difficult, an upgrade to this technique is to write
template<typename char_type>
std::basic_ostream<char_type> &operator<<(std::basic_ostream<char_type> &out, classA const &a) {
// rest as before. Put it in a header because it is a function template now.
}
This enables you to write classA objects not only to cout, cerr, clog, ofstream, ostringstream etc., but also to their wchar_t counterparts wcout, wcerr, wclog, wofstream, and wostringstream. These are rarely used in practice, but often it will cost you nothing to implement this feature. The trick is that std::ostream and std::wostream -- base classes of all these output streams -- are aliases for std::basic_ostream<char> and std::basic_ostream<wchar_t>, respectively. That gives us this nice way to handle both (and potentially other) character classes without code duplication.
clog can be an option if you want to log your steps of a process in some file and review the file later to see what goes wrong. Also you can check state of data members at certain interval by logging them externally in file.

Writing a class object into a file using fstream and then read it

I want to make a class of a student and take 3 inputs information and make an output of this file. How to this? This is my try:
#include <iostream>
using namespace std;
class Student{
private:
char name[50];
char id[50];
int age;
public:
void getdata()
{
//take name as input
//take id as input
//take age as input
}
void showdata()
{
//display stored file
}
}
int main()
{
Student s1;
ofstream s1("student.txt"); //i want to store that 's1' object
//anything else
return 0;
}
C++ uses the stream paradigm to implement standard input/output.
Stream paradigm means that if you application wants to access/use a resource (A file, the console, etc) a stream acts as a mediator between your application and the resource:
ofstream +----+
+-------------------->|File|
| +----+
|
+------+------+
| Application |
+------+------+
|
| +-------+
+-------------------->|Console|
cout +-------+
It means every write/read operations you perform are really stream operations. The point of this is that stream operations are basically the same, independently of what type of resource (And what type of stream) are you using.
This allows us to implement a "generic" (Generic meaning valid for any type of stream/resource). How? Overloading C++ operators >> and <<.
For input operations (Input means receiving data from the stream and put it in our variable/object), we need to overload the >> operator as follows:
istream& operator>>(istream& is , MyClass& object)
{
is >> object.myClassAtributte; (1)
... //Same for every attribute of your class.
return is;
}
First, note that the input stream is passed by reference. By reference because streams are non-copyable (What exactly means to copy a stream? Copy the link between your app and the resource? That sounds ridiculous), and non-const beacuse you are going to modify the stream (You are going to write through it).
Finally, note that the function not returns void, returns a reference to the same stream that was passed to the function. That allows you to write concatenated-write/read sentences like cout << "Hello. " << "Im" << " Manu343726" << endl;
For output operations (Output means sending data to the stream), we need to overload the << operator, wich implementation is exactly the same:
ostream& operator<<(ostream& os , const MyClass& object)
{
os << object.myClassAtributte; (1)
... //Same for every attribute of your class.
return os;
}
Note that in this case, your object is passed const, beacuse we won't modify it (We will only read its attributes).
(1) Is preferable to implement this functions making them friend of your class, to allow us access to private/protected members.
You have to overload << and >> operators for ostream and istream
std::ostream& operator<< (std::ostream& stream, const Student& student)
std::istream& operator<< (std::istream& stream, Student& student)
make them friend and implement

C++ Passing ostream as parameter

I'm working on a homework project for a virtual rolodex that has called for a main class, a rolodex class, and a card class. To output the contents of all of the "cards" to the console, the assignment says that main() should call a show(...) function in the rolodex class, passing it an ostream and show(...) then iterates over the cards, calling each of their showCard() functions. The actual showing is done by the card objects' showCard() function, showing on the provided ostream.
What I don't understand is why an ostream would/should be passed anywhere. Seems like the assignment is calling for something like this:
main() {
Rolodex myRolodex;
ostream myStream;
myRolodex.show(myStream);
}
void Rolodex::show(ostream& theStream) {
//for each card 'i' in the Rolodex...
myCard[i].show(theStream);
}
void Card::show(ostream& theStream) {
theStream << "output some stuff" << endl;
}
instead of something like this:
main() {
Rolodex myRolodex;
myRolodex.show(); //no ostream passed
}
void Rolodex::show() {
//for each card 'i' in the Rolodex...
myCard[i].show();//no ostream passed
}
void Card::show() {
cout << "output some stuff" << endl;
}
Am I either misunderstanding the use of ostream as a parameter or missing some other obvious reason to pass an ostream down the stream like that?
What I don't understand is why an ostream would/should be passed anywhere.
This is often used for things like testing. Say you want console output normally, so you'd pass around a reference to std::cout. But sometimes you want to do testing, e.g. unit or acceptance testing, and you want to store the output in memory for that. You could use std::stringstream for this, and the function you're working with is none the wiser.
That's one specific case -- but in general any place where you'd want to change where the data source or sink could be coming from / going to, you can do that by passing a stream around.
For example, the following would print your rolodex to the console:
int main()
{
Rolodex myRolodex;
myRolodex.show(std::cout);
}
... but if tomorrow you wanted to write to a file instead, you can do that without affecting the code inside Rolodex at all:
int main()
{
Rolodex myRolodex;
std::ofstream file("This\\Is\\The\\Path\\To\\The\\File.txt");
myRolodex.show(file); // Outputs the result to the file,
// rather than to the console.
}
I would just overload the << operator:
class Card{
public:
friend ostream& operator<<(ostream& os, const Card& s);
};
ostream& operator<<(ostream& os, const Card& s){
os << "Print stuff";
return os;
}
And you could overload in the Rolodex as well to just iterate over the cards.