Overload "<<" with heredity and polymorphism?

Below is an example of a rough example of how the code looks, the question is how can I have DerivedOne and DerivedTwo overload <<but save these objects in the Base * vector.

What do I want to achieve; I want to be able to scroll the vector of objects and display the information that I am talking about in DerivedOne and DerivedTwo.

vector<Base*> objects;

class Base
{
 private:
 object Data
 public:
 object getData() { return Data; }
};

class DerivedOne : public Base
{
}

class DerivedTwo : public Base
{
}

Now I know that this is, but it will not work for my purposes.

friend ostream &operator<<(ostream &stream, Object object)
{
    return stream << "Test" << endl;
}
+5
source share
3 answers

, , .

, :

#include <iostream>

namespace {
  class Base {
    // private (there is no need to call it in subclasses)
    virtual std::ostream& doprint(std::ostream&) const = 0;
  public:
    friend std::ostream& operator << (std::ostream& os, const Base& b) {
      return b.doprint(os); // polymorphic print via reference
    }

    virtual ~Base() {} // allow polymorphic delete
  };


  class DerivedOne : public Base {
    std::ostream& doprint(std::ostream& os) const {
      return os << "One";
    }
  public:
    DerivedOne() { std::cerr << "hi " << *this << "\n"; } // use << inside class
    ~DerivedOne() { std::cerr << "bye " << *this << "\n"; }
  };
}

#include <memory>
#include <vector>

int main () {
  using namespace std;
  // wrap Base* with shared_ptr<> to put it in a vector
  vector<shared_ptr<Base>> v{ make_shared<DerivedOne>() };
  for (auto i: v) cout << *i << " ";
  cout << endl;
}

hi One
One 
bye One
+12

- :

struct Base {
    virtual ~Base () {}
    virtual std::ostream & output (std::ostream &) const = 0;
};

std::ostream & operator << (std::ostream &os, const Base &b) {
    return b.output(os);
}

, operator<< Base, .

+5

, .

, :

  • " "? ( )?
  • ( )?
  • ( , )
  • ?
  • ?

, .

, , Base (, , ( : , ?) • ?)

(1.), , std::ostream&, . operator<<(std::ostream&, Base*), (std::ostream&, const std::vector<Base*>&)

:

class Base
{
    ...
public:
    virtual ~Base() {} //must be polymorphic
protected:
    virtual void out(std::ostream& s) =0;

    friend std::ostream& operator<<(std::ostream& st, Base* pb)
    { pb->out(st); return st; }
};

class Derived1: public Base
{
    ...
protected:
    virtual void out(std::ostream& s)
    {
        s << "Derived1 at " << this << " address " << std::endl;
    }
};


class Derived2: public Base
{
    ...
protected:
    virtual void out(std::ostream& s)
    {
        s << "Derived2 at " << this << " address " << std::endl;
    }
};

std::ostream& operator<<(std::ostream& s, const std::vector<Base*>& v)
{
    s << "there are " << v.size() << " objects:" << std::endl;
    for(auto& i:v)
        s << i;
    return s;
}

(2.), yopu ave a

class Derived3: public Base
{
    ...
    Base* ptrOwnedobject;
};

Derived3::out, .

(3.), , , , . - , , ( , ).

If you are in situation (4.), then what is said about (3.) becomes mandatory in order to avoid infinite recursion.

If you are in situation (5.), you should also find out which object the member belongs to (not trivial). If you also have multiple inheritance and virtual databases ... still harder.

+1
source

All Articles