Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>I know I'm a year late and a dollar short, but I'll pitch in my solution anyways.</p> <pre><code>//////// Base.. template&lt;typename DerivedBuilder, typename Options&gt; class Builder { protected: Builder() {} DerivedBuilder&amp; me() { return *static_cast&lt;DerivedBuilder*&gt;(this); } Options options; }; ////////////////////////// A ////////////////////////// class Options_A { public: Options_A() : a(7) {} int a; }; class Builder_A; class A { public: virtual ~A() {} virtual void print() { cout &lt;&lt; "Class A, a:" &lt;&lt; a &lt;&lt; endl; } protected: friend class Builder_A; A(const Options_A&amp; options) : a(options.a) {} int a; }; template&lt;typename DerivedBuilder, typename Options = Options_A&gt; class BuilderT_A : public Builder&lt;DerivedBuilder, Options&gt; { public: using Builder&lt;DerivedBuilder, Options&gt;::options; using Builder&lt;DerivedBuilder, Options&gt;::me; DerivedBuilder&amp; a(int p) { options.a = p; return me(); } }; class Builder_A : public BuilderT_A&lt;Builder_A&gt; { public: shared_ptr&lt;A&gt; create() { shared_ptr&lt;A&gt; obj(new A(options)); return obj; } }; ////////////////////////// B ////////////////////////// class Options_B : public Options_A { public: Options_B() : b(8) {} int b; }; class Builder_B; class B : public A { public: virtual ~B() {} virtual void print() { cout &lt;&lt; "Class B, a:" &lt;&lt; a &lt;&lt; ", b:" &lt;&lt; b &lt;&lt; endl; } protected: friend class Builder_B; B(const Options_B&amp; options) : A(options), b(options.b) {} int b; }; template&lt;typename DerivedBuilder, typename Options = Options_B&gt; class BuilderT_B : public BuilderT_A&lt;DerivedBuilder, Options&gt; { public: using Builder&lt;DerivedBuilder, Options&gt;::options; using Builder&lt;DerivedBuilder, Options&gt;::me; DerivedBuilder&amp; b(int p) { options.b = p; return me(); } }; class Builder_B : public BuilderT_B&lt;Builder_B&gt; { public: shared_ptr&lt;B&gt; create() { shared_ptr&lt;B&gt; obj(new B(options)); return obj; } }; ////////////////////////// C ////////////////////////// class Options_C : public Options_B { public: Options_C() : c(9) {} int c; }; class Builder_C; class C : public B { public: virtual ~C() {} virtual void print() { cout &lt;&lt; "Class C, a:" &lt;&lt; a &lt;&lt; ", b:" &lt;&lt; b &lt;&lt; ", c:" &lt;&lt; c &lt;&lt; endl; } protected: friend class Builder_C; C(const Options_C&amp; options) : B(options), c(options.c) {} int c; }; template&lt;typename DerivedBuilder, typename Options = Options_C&gt; class BuilderT_C : public BuilderT_B&lt;DerivedBuilder, Options_C&gt; { public: using Builder&lt;DerivedBuilder, Options&gt;::options; using Builder&lt;DerivedBuilder, Options&gt;::me; DerivedBuilder&amp; c(int p) { options.c = p; return *static_cast&lt;DerivedBuilder*&gt;(this); } }; class Builder_C : public BuilderT_C&lt;Builder_C&gt; { public: shared_ptr&lt;C&gt; create() { shared_ptr&lt;C&gt; obj(new C(options)); return obj; } }; /////////////////////////////////////////////////////////////////////////// int main() { shared_ptr&lt;A&gt; a = Builder_A().a(55).a(1).create(); a-&gt;print(); shared_ptr&lt;B&gt; b = Builder_B().b(99).b(2).a(88).b(4).a(2).b(3).create(); b-&gt;print(); shared_ptr&lt;C&gt; c = Builder_C().a(99).b(98).c(97).a(96).c(6).b(5).a(4).create(); c-&gt;print(); return 0; } /* Output: Class A, a:1 Class B, a:2, b:3 Class C, a:4, b:5, c:6 */ </code></pre> <p>C derives from B, and B derives from A. I've repeated parameters to show they can put in any order desired. </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