2

I have the following problem.

I've created an array of pointers to objects from the base class, but I'm storing in this array also the pointers to the objects from the derived classes.

I also overloaded the <<operator in each class to display the objects. However, when I apply this overloaded <<operator to the above mentioned array, it treats all the pointers as if there were pointing to the objects of the base class.

Below I present the code that depicts the problem. I need this overloaded operator to work correctly because I need to save the objects pointed by the array in the file.

    #include <iostream> 
    #include <cstdio>
    #include <cstdlib>

    using namespace std;

    class Base
    {
       public:
       int basevar;
       Base(): basevar(1) {};
       virtual void dosth(){};
       friend ostream & operator<<(ostream & screen, const Base & obj);
    };

    ostream & operator<<(ostream & screen, const Base & obj)
    {
       screen << obj.basevar;
       return screen;
    };

    class Der1: public Base
    { 
        public:
        int de1;
        Der1(): de1(2) {};
        virtual void dosth()
        {
           cout << "Der1" << endl;
        }
        friend ostream & operator<<(ostream & screen, const Der1 & obj);
    };

    ostream & operator<<(ostream & screen, const Der1 & obj)
    {
       Base b;
       b = static_cast <Base>(obj); 
       screen << b; 
       screen << " " << obj.de1;
       return screen;
    };

    class Der2: public Base
    { 
        public:
        int de2;
        Der2(): de2(3) {};
        virtual void dosth()
        {
           cout << "Der2" << endl;
        }
        friend ostream & operator<<(ostream & screen, const Der2 & obj);
    };

    ostream & operator<<(ostream & screen, const Der2 & obj)
    {
        Base b;
        b = static_cast <Base>(obj); 
        screen << b; 
        screen << " " << obj.de2; 
        return screen; 
    }

    int main()
    {
         Base * array[] = {new Base(), new Der1(), new Der2()};
         for(int i=0; i<3; ++i)
         {
             cout << *array[i]; // <- always displays objects as if they were from the base class
         }
         return 0;
    }
Ziezi
  • 6,375
  • 3
  • 39
  • 49
Me_me_me
  • 124
  • 1
  • 9
  • possible duplicate of [Making operator<< virtual?](http://stackoverflow.com/questions/4571611/making-operator-virtual) – Petr May 16 '15 at 19:24

1 Answers1

4

You can declare a virtual function in the base class the following way

class Base
{
   public:
   int basevar;
   Base(): basevar(1) {};
   virtual std::ostream & out( std::ostream &os ) const
   {
       return os << basevar;
   }

   virtual void dosth(){};
   friend ostream & operator<<(ostream & screen, const Base & obj);
};

In this case the operator will look like

ostream & operator<<(ostream & screen, const Base & obj)
{
    return obj.out( screen );
};

and in derived classes redefine the virtual function. For example

class Der1: public Base
{ 
    public:
    int de1;
    Der1(): de1(2) {};
    std::ostream & out( std::ostream &os ) const
    {
       return Base::out( os ) << " " << obj.de1;
    }
    virtual void dosth()
    {
       cout << "Der1" << endl;
    }
};

In this case there is no need to define the operator for derived classes.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335