I'd like to know how do stream classes work in C++. When you say:
cout<<"Hello\n";
What does exactly do "<<". I know that cout is an object form iostream that represents the standard output stream oriented to narrow characters (char).
In C "<<" is the bitwise shift operator so it moves bits to the left but in C++ it's and insertion operator. Well, that's all I know, I don't really understand how does this work under the hood.
What I'm asking for is detailed explanation about stream classes in C++, how they are defined and implemented.
Thank you very much for your time and sorry for my English.
A stream is basically a sequence of data. Whatever data we use in our programming flows through a stream. A stream can be thought of as a channel connecting a processor or logic unit (where data is processed according to the instructions) and input and output devices.
We have 3 kinds of I/O streams in C: stdin (standard input) stdout (standard output) stderr (standard error)
Explanation: ofstream is a stream class to write on files.
Let's create a class that looks like cout
(but without as many bells and whistles).
#include <string>
class os_t {
public:
os_t & operator<<(std::string const & s) {
printf("%s", s.c_str());
return *this;
}
};
int main() {
os_t os;
os << "hello\n";
os << "chaining " << "works too." << "\n";
}
Notes:
operator<<
is an operator overload just like operator+
or all of the other operators.return *this;
.os_t
class because someone else wrote it?We don't have to use member functions to define this functionality. We can also use free functions. Let's show that as well:
#include <string>
class os_t {
public:
os_t & operator<<(std::string const & s) {
printf("%s", s.c_str());
return *this;
}
};
os_t & operator<<(os_t & os, int x) {
printf("%d", x);
return os;
// We could also have used the class's functionality to do this:
// os << std::to_string(x);
// return os;
}
int main() {
os_t os;
os << "now we can also print integers: " << 3 << "\n";
}
A great example of how this kind of logic is useful can be found in the GMP library. This library is designed to allow arbitrarily large integers. We do this, by using a custom class. Here's an example of it's use. Note that operator overloading let's us write code that looks almost identical to if we were using the traditional int
type.
#include <iostream>
#include <gmpxx.h>
int main() {
mpz_class x("7612058254738945");
mpz_class y("9263591128439081");
x = x + y * y;
y = x << 2;
std::cout << x + y << std::endl;
}
<<
is a binary operator in C++, and thus can be overloaded.
You know of the C usage of this operator, where 1 << 3
is a binary operation returning 8
. You could think of this as the method int operator<<(int, int)
where passing in arguments 1
and 3
returns 8
.
Technically, operator<<
could do anything. It's just an arbitrary method call.
By convention in C++, the <<
operator is used for handling streams in addition to being the bit-shift operator. When you perform cout << "Hello!"
, you are calling a method with prototype ostream & operator<< (ostream & output, char const * stream_me)
. Note the return value ostream &
. That return allows you to call the method multiple times, like std::cout << "Hello World" << "!";
which is calling operator<<
twice... once on std::cout and "Hello World", and the second time on the result of that first invocation and "!".
In general, if you were to create a class named class Foo
, and you wanted it to be printable, you could define your printing method as ostream & operator<< (ostream & output, Foo const & print_me)
. Here is a simple example.
#include <iostream>
struct Circle {
float x, y;
float radius;
};
std::ostream & operator<< (std::ostream & output, Circle const & print_me) {
output << "A circle at (" << print_me.x << ", " << print_me.y << ") with radius " << print_me.radius << ".";
}
int main (void) {
Circle my_circle;
my_circle.x = 5;
my_circle.y = 10;
my_circle.radius = 20;
std::cout << my_circle << '\n';
return 0;
}
Operators can be considered functions with syntactic sugar that allow for clean syntax. This is simply a case of operator overloading.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With