Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Ideally you have a static and perhaps a non-static <code>create()</code> functions. There is a clever way to accomplish this.</p> <ol> <li><p>Define a <code>SuperBase</code> class. It needs a virtual destructor and a pure virtual <code>create()</code> function. You'll use pointers/references to this class for normal late-binding OOP behaviours.</p></li> <li><p>Define a <code>Base</code> class template that inherits from <code>SuperBase</code>. <code>Base</code>'s template parameter will be the type of the <code>Derived</code> class. <code>Base</code> will also have a traits class template with a static function called <code>create()</code>. This static <code>create()</code> function will create a default object with <code>new</code>. Using the trait's <code>create()</code> function, <code>Base</code> will define both a <code>static_create()</code> and the pure virtual <code>SuperBase::create()</code> functions.</p></li> <li><p>Implement <code>Derived</code> by inheriting from <code>Base&lt;Derived&gt;</code>.</p></li> </ol> <p>One this is done, if you know you are using a derived type, then you can write <code>Derived::create()</code> to statically create a new one. If not, then you can always use an instance's <code>create()</code> method. Polymorphism is not broken since <code>SuperBase</code> would have the polymorphic interface you need/want --<code>Base&lt;D&gt;</code> is simply a helper class that auto defines the <code>static_create()</code> and <code>create()</code> functions so you would not normally use <code>Base&lt;D&gt;</code> directly.</p> <p>Sample code appears below:</p> <pre><code>#include &lt;memory&gt; #include &lt;iostream&gt; class SuperBase { public: virtual ~SuperBase() = default; virtual std::shared_ptr&lt;SuperBase&gt; create() const = 0; }; template &lt;typename T&gt; struct Base_Traits { static T* create() { return new T; } }; template &lt;typename Derived, typename Traits=Base_Traits&lt;Derived&gt;&gt; class Base : public SuperBase { public: // Define a static factory function... static std::shared_ptr&lt;SuperBase&gt; static_create() { return std::shared_ptr&lt;SuperBase&gt;{Traits::create()}; } // Define pure virtual implementation... std::shared_ptr&lt;SuperBase&gt; create() const override { return static_create(); } }; class Derived : public Base&lt;Derived&gt; { }; int main() { auto newone = Derived::static_create(); // Type known @ compile time auto anotherone = newone-&gt;create(); // Late binding; type not known @ compile time } </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
 

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