Overloaded stream insertion operator (<<) in the sub-class - c++

I have a class A, for which I have defined an (overloaded) stream insertion operator. I publicly derive a class B from this class A, which has an additional data member. Therefore I'll need to redefine the overloaded stream insertion operator for the derived class and I've do it this way:
#include <iostream>
using namespace std;
class A {
int i;
char c;
public:
A(int i = 0, char c = ' ') {
this->i = i;
this->c = c;
}
friend ostream& operator << (ostream&, const A&);
};
class B : public A {
double d;
public:
B(int i = 0, char c = ' ', double d = 0.0) : A(i, c), d(d) {}
friend ostream& operator << (ostream&, const B&);
};
ostream& operator << (ostream& out, const A& a) {
out << "\nInteger: " << a.i << "\nCharacter: " << a.c << endl;
return out;
}
ostream& operator << (ostream& out, const B& b) {
out << b;
out << "\nDouble: " << b.d << endl;
return out;
}
int main() {
A a(10, 'x');
B b(20, 'y', 5.23);
cout << b;
return 0;
}
Question-1: Is this an appropriate technique of doing so? If not, kindly let me know where I'm going wrong.
Question-2: On running, this program crashes. Why so?

One common way to support this is to have the overloaded operator invoke a virtual member function:
class A {
public:
virtual std::ostream &write(std::ostream &os) const {
// write self to os
os << "A\n";
return os;
}
};
class B : public A {
public:
virtual std::ostream &write(std::ostream &os) const {
// write self to os
// This can use the base class writer like:
A::write(os);
os << "B\n";
return os;
}
};
Then the operator overload just invokes that member function:
std::ostream &operator<<(std::ostream &os, A const &a) {
return a.write(os);
}
Since write is virtual and you're passing the A by (const) reference, this invokes the correct member function based on the actual type (i.e., A::write if the object is really an instance of A, and B::write if it's an instance of B).
For example, we could exercise these something like this:
int main() {
A a;
B b;
std::cout << a << "\n";
std::cout << b << "\n";
}
...which produces output like this:
A
A
B
In real use, you probably want to make the write functions protected, and make the operator<< a friend of A.

The program crashes because your second insertion operator calls itself:
ostream& operator << (ostream& out, const B& b) {
out << b; // <--YIKES!
out << "\nDouble: " << b.d << endl;
return out;
}
Generally this is a good approach, although I prefer to give the classes a public virtual print(ostream&) const function, and have the insertion operator call that.

Related

How to properly define and call original operator<<

Consider the following example:
#include <iostream>
class A {
const int i;
const int j;
public:
A(int i_, int j_) : i(i_), j(j_) {}
std::ostream& operator<<(std::ostream& o) const {
o << "i is " << i << ", j is " << j;
return o;
}
};
std::ostream& operator<<(std::ostream& o, const A& a ) {
o << "This is A: ";
a.operator<<(o);
return o;
}
int main() {
A a(0,42);
std::cout << a << std::endl;
return 0;
}
It will generate the following output:
This is A: i is 0, j is 42
The output is correct but I don't like how I am calling A's original operator<<.
I am trying to figure out how to properly define that operator, so it could be called this way:
o << "This is A: " << (some magic)a;
instead of
o << "This is A: ";
a.operator<<(o);
I have tried various ways but either I get to ambiguity issues or getting an address of the std::cout and broken string. Notice that the result std::ostream& of A::operator<< is a remnant of my tests. In the example above it would suffice to use void.
Is it possible without creating an intermediate class B that derives from class A and defines its own operator<< (class NiceOutputOfA : public A {...};) ?
Binary operators defined in-class always have the class as the left-hand side operand. Which means you cannot implement stream insertion/extraction in-class.
Probably the most common way is to implement the operator as a friend defined inline in the class.
Another reasonably common way is to provide a named streaming function in the class, and an out-of-class streaming operator which calls that function. You almost did that, but named that function operator <<.
The closest resolution I came to is by creating an intermediate class:
class Decorate {
const A& a;
public:
Decorate(const A& a_) : a(a_) {}
friend std::ostream& operator<<(std::ostream& o, const PrintA& pa) {
o << "This is A: " << pa.a;
return o;
}
};
and having it printed this way:
int main() {
A a(0,42);
std::cout << Decorate(a) << std::endl;
return 0;
}
I was looking for something prettier but based on Angew's answer I lost hope to have it done suing proper operator<< declaration.
Thanks for all your help!
Marking Angew's response as the answer.

How to invoke an overloaded parent cout friend class from a derived class?

Imagine a setup as follows. How do I invoke the base class cout from within the derived class cout? I could use the getBrand() method, but I feel like I should be able to directly access the base class' cout friend function.
I hacked a bit, and tried this.Brand and also just Brand. No luck.
class Brand {
public:
Brand(std::string brand):brand_(brand) {};
friend std::ostream & operator << (std::ostream & out, const Brand & b) {
out << b.brand_ << ' ';
return out;
}
std::string getBrand()const { return brand_; }
private:
std::string brand_;
}
class Cheese : public Brand {
public:
Cheese(std::string brand, std::string type):Brand(brand), type_(type) {};
friend std::ostream & operator << (std::ostream & out, const Cheese & c) {
out << /* THIS.BRAND?! BRAND?! getBrand() meh.. */ << ' ' << c.type_ << std::endl; // <-- HERE
return out;
}
private:
std::string type_;
}
int main() {
Cheese c("Cabot Clothbound", "Cheddar");
std::cout << c << std::endl;
}
DESIRED OUTPUT
Cabot Clothbound Cheddar
You could invoke the overloaded operator << of the Base class from the derived class. Since, you declared the operator as a friend, you could simply cast the the derived class to a base class:
class Cheese : public Brand {
public:
Cheese(std::string brand, std::string type):Brand(brand), type_(type) {};
friend std::ostream & operator << (std::ostream & out, const Cheese & c) {
//ADDED
out << static_cast<const Brand&>(c) << c.type_ << std::endl;
return out;
}
private:
std::string type_;
};
Output:
Cabot Clothbound Cheddar
See it Live
Cast it, like this:
friend std::ostream& operator<<(std::ostream& out, const Cheese& c)
{
out << static_cast<const Brand &>(c);
out << c.type_ << std::endl;
return out;
}
All other answers are responding correctly to your specific question, but whenever you'll try to use polymorphism like this:
Brand const &c = Cheese("Cabot Clothbound", "Cheddar");
std::cout << c << std::endl;
operator << corresponding to Brand will be called instead of Cheese's.
The good way to do it is to use a virtual print member function:
class Brand {
public:
Brand(std::string const & brand):brand_(brand) {}
virtual ~Brand() {}
virtual void print(std::ostream & out) const {
out << brand_;
}
std::string const & getBrand()const { return brand_; }
private:
std::string brand_;
};
class Cheese : public Brand {
public:
Cheese(std::string const & brand, std::string const & type):Brand(brand), type_(type) {}
void print(std::ostream & out) const override {
Brand::print(out); // calling base print()
out << ' ' << type_ << std::endl;
}
private:
std::string type_;
};
Then, you only need a single operator << for the base class which will call your print virtual member function:
std::ostream & operator << (std::ostream & out, const Brand & b) {
b.print(out);
return out;
}
DEMO
You obviously can't do anything like Brand::operator<<, because both operator<< are defined as friend and thus they are not member functions.
If you want to invoke operator<<(std::ostream&, const Brand&), you just have to pass correct types to that, and since Derived classes can be easily casted to Base classes, you can just do
friend std::ostream & operator << (std::ostream & out, const Cheese & c) {
out << static_cast<const Brand&>(c) << ' ' << c.type_ << std::endl;
return out;
}

Operator << overload inheritance, why I got input from base class, instead of child class?

I have a class, let's call it A, it has only one field, aa. I have another class, B, which inherits class A, and instead of having the aa field, it also has its own field, bb. Now, I overloaded operator << (cout) for both classes. I tried to use polimorphism, but it seems that polimorphism does not work properly with operators. My code shows me only aa field when using operator cout for showing the object obj.
I mean, do I always need to add the virtual word to overload the function from the base class in a child class? If so, how should I do the same with operators, operators can't be virtual ...
#include <iostream>
#include <ostream>
using namespace std;
class A
{
protected :
int aa;
public:
A(int aa) {this->aa = aa;}
~A(){}
friend ostream &operator<<(ostream &os, const A& obj);
virtual void show() {cout << "a = " << aa << "\n"; }
};
ostream &operator<<(ostream &os, const A& obj)
{
for(int i=0; i<80; i++)
os << "-";
os << "\n";
os << "a = " << obj.aa << "\n";
for(int i=0; i<80; i++)
os << "-";
os << "\n";
return os;
}
class B : public A
{
private :
int bb;
public:
B(int aa, int bb) : A(aa) {this->bb = bb;}
~B(){}
friend ostream &operator<<(ostream &os, const B& obj);
void show() {cout << "a = " << aa << "\n"; cout << "b = " << bb << "\n";}
};
ostream &operator<<(ostream &os, const B& obj)
{
for(int i=0; i<80; i++)
os << "-";
os << "\n";
os << "a = " << obj.aa << "\n";
os << "b = " << obj.bb << "\n";
for(int i=0; i<80; i++)
os << "-";
os << "\n";
return os;
}
int main()
{
A *obj = new B(2,3);
cout << *obj;
obj->show();
delete obj;
return 0;
}
I mean, do I always need to add the virtual word to overload the function from the base class in a child class? If so, how should I do the same with operators, operators can't be virtual ...
Sure they can. But only member functions can be virtual, and these operators are not members functions - they're global functions.
In this case, you can't make them member functions (because the first parameter isn't an instance of your class). But you could create a virtual member function and have the operator call it:
class A
{
protected:
virtual void print(ostream &);
public:
friend ostream &operator<<(ostream &os, const A& obj);
// ... other stuff ...
};
ostream &operator<<(ostream &os, const A& obj)
{
obj.print(os);
return os;
}
and then override print instead of operator<<.

How can I use cout << myclass

myclass is a C++ class written by me and when I write:
myclass x;
cout << x;
How do I output 10 or 20.2, like an integer or a float value?
Typically by overloading operator<< for your class:
struct myclass {
int i;
};
std::ostream &operator<<(std::ostream &os, myclass const &m) {
return os << m.i;
}
int main() {
myclass x(10);
std::cout << x;
return 0;
}
You need to overload the << operator,
std::ostream& operator<<(std::ostream& os, const myclass& obj)
{
os << obj.somevalue;
return os;
}
Then when you do cout << x (where x is of type myclass in your case), it would output whatever you've told it to in the method. In the case of the example above it would be the x.somevalue member.
If the type of the member can't be added directly to an ostream, then you would need to overload the << operator for that type also, using the same method as above.
it's very easy, just implement :
std::ostream & operator<<(std::ostream & os, const myclass & foo)
{
os << foo.var;
return os;
}
You need to return a reference to os in order to chain the outpout (cout << foo << 42 << endl)
Even though other answer provide correct code, it is also recommended to use a hidden friend function to implement the operator<<. Hidden friend functions has a more limited scope, therefore results in a faster compilation. Since there is less overloads cluttering the namespace scope, the compiler has less lookup to do.
struct myclass {
int i;
friend auto operator<<(std::ostream& os, myclass const& m) -> std::ostream& {
return os << m.i;
}
};
int main() {
auto const x = myclass{10};
std::cout << x;
return 0;
}
Alternative:
struct myclass {
int i;
inline operator int() const
{
return i;
}
};

C++ equivalent of Java's toString?

I'd like to control what is written to a stream, i.e. cout, for an object of a custom class. Is that possible in C++? In Java you could override the toString() method for similar purpose.
In C++ you can overload operator<< for ostream and your custom class:
class A {
public:
int i;
};
std::ostream& operator<<(std::ostream &strm, const A &a) {
return strm << "A(" << a.i << ")";
}
This way you can output instances of your class on streams:
A x = ...;
std::cout << x << std::endl;
In case your operator<< wants to print out internals of class A and really needs access to its private and protected members you could also declare it as a friend function:
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 << ")";
}
You can also do it this way, allowing polymorphism:
class Base {
public:
virtual std::ostream& dump(std::ostream& o) const {
return o << "Base: " << b << "; ";
}
private:
int b;
};
class Derived : public Base {
public:
virtual std::ostream& dump(std::ostream& o) const {
return o << "Derived: " << d << "; ";
}
private:
int d;
}
std::ostream& operator<<(std::ostream& o, const Base& b) { return b.dump(o); }
In C++11, to_string is finally added to the standard.
http://en.cppreference.com/w/cpp/string/basic_string/to_string
As an extension to what John said, if you want to extract the string representation and store it in a std::string do this:
#include <sstream>
// ...
// Suppose a class A
A a;
std::stringstream sstream;
sstream << a;
std::string s = sstream.str(); // or you could use sstream >> s but that would skip out whitespace
std::stringstream is located in the <sstream> header.
The question has been answered. But I wanted to add a concrete example.
class Point{
public:
Point(int theX, int theY) :x(theX), y(theY)
{}
// Print the object
friend ostream& operator <<(ostream& outputStream, const Point& p);
private:
int x;
int y;
};
ostream& operator <<(ostream& outputStream, const Point& p){
int posX = p.x;
int posY = p.y;
outputStream << "x="<<posX<<","<<"y="<<posY;
return outputStream;
}
This example requires understanding operator overload.