Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>In fact, it's a more general issue than serialization called <code>Virtual Constructor</code>.</p> <p>The traditional approach is to a <code>Factory</code>, which based on an ID returns the right derived type. There are two solutions:</p> <ul> <li>the <code>switch</code> method as you noticed, though you need to allocate on the heap</li> <li>the <code>prototype</code> method</li> </ul> <p>The prototype method goes like so:</p> <pre><code>// Cloneability class Base { public: virtual Base* clone() const = 0; }; class Derived: public Base { public: virtual Derived* clone() const { return new Derived(*this); } }; // Factory class Factory { public: Base* get(std::string const&amp; id) const; void set(std::string const&amp; id, Base* exemplar); private: typedef std::map &lt; std::string, Base* &gt; exemplars_type; exemplars_type mExemplars; }; </code></pre> <p>It is somewhat traditional to make the <code>Factory</code> a singleton, but it's another matter entirely.</p> <p>For deserialization proper, it's easier if you have a virtual method <code>deserialize</code> to call on the object. </p> <p><strong>EDIT:</strong> How does the Factory work ?</p> <p>In C++ you can't create a type you don't know about. The idea above is therefore that the task of building a <code>Derived</code> object is given to the <code>Derived</code> class, by way of the <code>clone</code> method.</p> <p>Next comes the <code>Factory</code>. We are going to use a <code>map</code> which will associate a "tag" (for example <code>"Derived"</code>) to an instance of an object (say <code>Derived</code> here).</p> <pre><code>Factory factory; Derived derived; factory.set("Derived", &amp;derived); </code></pre> <p>Now, when we want to create an object which type we don't know at compile time (because the type is decided on the fly), we pass a tag to the factory and ask for an object in return.</p> <pre><code>std::unique_ptr&lt;Base&gt; base = factory.get("Derived"); </code></pre> <p>Under the cover, the <code>Factory</code> will find the <code>Base*</code> associated to the <code>"Derived"</code> tag and invoke the <code>clone</code> method of the object. This will actually (here) create an object of runtime-type <code>Derived</code>.</p> <p>We can verify this by using the <code>typeid</code> operator:</p> <pre><code>assert( typeid(base) == typeid(Derived) ); </code></pre>
 

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