Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>The smallest change to your code would be changing:</p> <pre><code>class SubObjectInt : public SubObject&lt;int&gt; { }; </code></pre> <p>to</p> <pre><code>typedef SubObject&lt;int&gt; SubObjectInt; </code></pre> <p>The currently failing definition will now compile and return a valid pointer.</p> <p>If you want particular code to be specific to SubObjectInt that is distinct from SubObject, then you could instead have:</p> <pre><code>template&lt;class T&gt; class SubObject : public Object { public: typedef SubContainer&lt;SubObject&lt;T&gt; &gt; ContainerType; ContainerType* GetSubContainer() { Container* container = GetContainer(); return dynamic_cast&lt;ContainerType*&gt;(container); } void TestMe() { ContainerType* pSubContainer = GetSubContainer(); assert(pSubContainer); } }; </code></pre> <p>And then your test code looks something like:</p> <pre><code>SubObjectInt::ContainerType* pContainer = new SubObjectInt::ContainerType(); SubObjectInt* pObject = new SubObjectInt(); pContainer-&gt;SetObject(pObject); pObject-&gt;TestMe(); </code></pre> <p>EDIT: in response to first comment</p> <p>well i would say you might be better off using a different design, you are intermingling inheritance and composition and templates in a way that is complicating what i think you want to achieve.</p> <p>you have a container type that you want to be able to assign objects. you have an object type that wants to know about its container.</p> <p>you want container and object types that do some things the same and some things differently depending on their contents.</p> <p>i would suggest something along these lines:</p> <pre><code>template&lt;class T&gt; class ObjectStrategy { public: virtual void execute(T* object) { std::cout &lt;&lt; "oh noes i am a default general ObjectStrategy" &lt;&lt; std::endl; } }; template&lt;class T&gt; class ContainerStrategy { public: virtual void execute(T* container) { std::cout &lt;&lt; "oops i am a default general ContainerStrategy" &lt;&lt; std::endl; } }; template&lt;class T&gt; class Object; template&lt;class T&gt; class Container { public: Container() : m_pObject(0), m_strategy(new ContainerStrategy&lt;Container&lt;T&gt; &gt;()) { } Container(ContainerStrategy&lt;Container&lt;T&gt; &gt;* strategy_override) : m_pObject(0), m_strategy(strategy_override) { } ~Container() { delete m_strategy; } void SetObject(T* pObject) { m_pObject = pObject; m_pObject-&gt;SetContainer(this); } void DoContainerStuff() { m_strategy-&gt;execute(this); } protected: T* m_pObject; ContainerStrategy&lt;Container&lt;T&gt; &gt;* m_strategy; }; template&lt;class T&gt; class Object { public: Object() : m_pContainer(0), m_strategy(new ObjectStrategy&lt;Object&lt;T&gt; &gt;()) { } Object(ObjectStrategy&lt;Object&lt;T&gt; &gt;* strategy_override) : m_pContainer(0), m_strategy(strategy_override) { } ~Object() { delete m_strategy; } Container&lt;Object&lt;T&gt; &gt;* GetContainer() { return m_pContainer; } void SetContainer(Container&lt;Object&lt;T&gt; &gt;* pContainer) { m_pContainer = pContainer; } void DoObjectStuff() { m_strategy-&gt;execute(this); } void TestMe() { DoObjectStuff(); Container&lt;Object&lt;T&gt; &gt;* pContainer = GetContainer(); pContainer-&gt;DoContainerStuff(); } protected: Container&lt;Object&lt;T&gt; &gt;* m_pContainer; ObjectStrategy&lt;Object&lt;T&gt; &gt;* m_strategy; }; typedef Object&lt;int&gt; ObjectInt; template&lt;&gt; class ObjectStrategy&lt;ObjectInt&gt; { public: virtual void execute(ObjectInt* container) { std::cout &lt;&lt; "omg i am a default specific strategy for ObjectInt" &lt;&lt; std::endl; } }; typedef Container&lt;ObjectInt&gt; ContainerObjectInt; template&lt;&gt; class ContainerStrategy&lt;ContainerObjectInt&gt; { public: virtual void execute(ContainerObjectInt* container) { std::cout &lt;&lt; "pow i am a default specific strategy for ContainerObjectInt" &lt;&lt; std::endl; } }; class ObjectIntOverrideStrategy : public ObjectStrategy&lt;ObjectInt&gt; { public: virtual void execute(ObjectInt* object) { std::cout &lt;&lt; "bam i am an overriding specific strategy for ObjectInt" &lt;&lt; std::endl; } }; class ContainerObjectIntOverrideStrategy : public ContainerStrategy&lt;ContainerObjectInt&gt; { public: virtual void execute(ContainerObjectInt* object) { std::cout &lt;&lt; "woo i am an overriding specific strategy ContainerObjectInt" &lt;&lt; std::endl; } }; int main(int argc, char** argv) { { // test with default + general strategies typedef Object&lt;float&gt; ObjectFloat; typedef Container&lt;ObjectFloat&gt; ContainerObjectFloat; ObjectFloat* pObject = new ObjectFloat(); ContainerObjectFloat* pContainer = new ContainerObjectFloat(); pContainer-&gt;SetObject(pObject); pObject-&gt;TestMe(); } { // test with default + specific strategies ObjectInt* pObject = new ObjectInt; ContainerObjectInt* pContainer = new ContainerObjectInt; pContainer-&gt;SetObject(pObject); pObject-&gt;TestMe(); } { // test with overriding + specific strategies ObjectInt* pObject = new ObjectInt(new ObjectIntOverrideStrategy); ContainerObjectInt* pContainer = new ContainerObjectInt(new ContainerObjectIntOverrideStrategy); pContainer-&gt;SetObject(pObject); pObject-&gt;TestMe(); } return 0; } </code></pre> <p>common functionality of objects or containers are implemented as member functions of object or container respectively.</p> <p>per-type functionality of objects or containers are implemented via composition of strategy objects, you could use a factory to produce appropriate objects and containers based on appropriate strategies. </p> <p>ive put forward a fairly flexible approach (maybe too flexible), so you could ignore template specialization or inheritance on the strategy objects depending on how specific you need the behaviour.</p>
    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.
    2. 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