指向包含派生类对象和重载<<的基类的指针数组操作者

时间:2015-05-16 19:22:50

标签: c++ pointers

我有以下问题。

我已经创建了一个指向基类对象的指针数组,但是我在这个数组中也存储了派生类中对象的指针。

我还重载了每个类中的<<operator来显示对象。 但是,当我将此重载<<operator应用于上述数组时,它会将所有指针视为指向基类的对象。

下面我将介绍描述问题的代码。 我需要这个重载的运算符才能正常工作,因为我需要将数组指向的对象保存在文件中。

    #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;
    }

1 个答案:

答案 0 :(得分:3)

您可以通过以下方式在基类中声明虚函数

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);
};

在这种情况下,操作员看起来像

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

并在派生类中重新定义虚函数。例如

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;
    }
};

在这种情况下,不需要为派生类定义运算符。