Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>As far your problem is described you have a collection of dynamically allocated polymorphic objects.</p> <p>The solution can change depending on how these object adhere to certain design disciplines:</p> <ol> <li>are you object "leaf only objects"? (not referring to other object themselves)?</li> <li>are there just single acyclic references (do your object form only trees of subobjects)?</li> <li>are there multiple path between references (a same object referred by two or more)</li> <li>are there cyclic references?</li> <li>are there references to other object <em>members</em>?</li> </ol> <p>The situation can become very complex depending on the situation and depending if you can tolerate or not multiple output of a same object and how can you break eventual loops.</p> <p>A first thing you cannot do is use <code>Base</code> as a value parameter (like in your , since that creates a copy (admitting your objects are copyable: if they refer to other object what does a copy do? multiplies the paths? Clones the referred object as well?)</p> <p>If you are in situation (1.), you just need a virtual function taking <code>std::ostream&amp;</code>, to be overridden in all the leaf objects. Then you need an overload for <code>operator&lt;&lt;(std::ostream&amp;, Base*)</code> and another for <code>(std::ostream&amp;, const std::vector&lt;Base*&gt;&amp;)</code></p> <p>like this:</p> <pre><code>class Base { ... public: virtual ~Base() {} //must be polymorphic protected: virtual void out(std::ostream&amp; s) =0; friend std::ostream&amp; operator&lt;&lt;(std::ostream&amp; st, Base* pb) { pb-&gt;out(st); return st; } }; class Derived1: public Base { ... protected: virtual void out(std::ostream&amp; s) { s &lt;&lt; "Derived1 at " &lt;&lt; this &lt;&lt; " address " &lt;&lt; std::endl; } }; class Derived2: public Base { ... protected: virtual void out(std::ostream&amp; s) { s &lt;&lt; "Derived2 at " &lt;&lt; this &lt;&lt; " address " &lt;&lt; std::endl; } }; std::ostream&amp; operator&lt;&lt;(std::ostream&amp; s, const std::vector&lt;Base*&gt;&amp; v) { s &lt;&lt; "there are " &lt;&lt; v.size() &lt;&lt; " objects:" &lt;&lt; std::endl; for(auto&amp; i:v) s &lt;&lt; i; return s; } </code></pre> <p>If you are in sutuation (2.) yopu may ave a </p> <pre><code>class Derived3: public Base { ... Base* ptrOwnedobject; }; </code></pre> <p>You can simply implement the <code>Derived3::out</code> function to recourse into the owned child.</p> <p>If you are in situation (3.), and you cannot tolerate a same object to be printed more time you ave different parents sharing a same child. You should somehow mark the child so that you don't save it twice or more, and un-mark all of the children after finishing the printing (you will most likely set up that mechanism into the Base class).</p> <p>If you are in situation (4.) then what said about (3.) becomes mandatory to avoid infinite recursion.</p> <p>If you are in situation (5.) you must also discover which object a member belongs (not trivial). If you also have multiple inheritance and virtual bases... things are even more complex.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload