, .
, :
, .
, , 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.
source
share