2

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;
}
yak
  • 3,770
  • 19
  • 60
  • 111

1 Answers1

2

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<<.

user253751
  • 57,427
  • 7
  • 48
  • 90
  • And if I made them member functions, what then? – yak Apr 05 '16 at 22:55
  • @yak If you added `ostream &operator<<(ostream &os)` as a member function then you could do `*obj << cout`. – user253751 Apr 05 '16 at 22:57
  • Thank you. And what about other operators, like, let's say, the `++` and `--` operators? I overloaded one of them, and I don't understand why I'm getting the seg fault with this code: http://pastie.org/private/rtsoerb0whoskzayu3ijq. I thought that class `B` inheriths all the overloaded operators from class `A`. – yak Apr 05 '16 at 23:01
  • @yak Could possibly be because your `operator++` function doesn't return any value. – user253751 Apr 05 '16 at 23:08
  • That's one thing - thank you for this. It now compiles just fine, I only needed to change `++obj;` to `++*obj;`, hm, strange. – yak Apr 05 '16 at 23:10
  • @yak Oh, didn't notice that. Yes, in that case, after `++obj` `obj` doesn't point to a valid object, so dereferencing it (with `obj->show();`) is likely to crash. And `delete obj;` is even more likely to crash, because it no longer matches a pointer returned by `new`. – user253751 Apr 05 '16 at 23:11