Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>If the goal is just to reduce the number of arguments supplied to the constructor, there are many ways to achieve that. The real question is, as I understand it from the comments to my first post, is if there is an easier way to manage the parameters.</p> <p>One way to make the parameters easier to manage is to use a general data structure to maintain them. Something like a map.</p> <pre><code>enum AttrTag { AT_Name, AT_Max_HP, AT_Max_MP, //... AT_Spells }; struct Attributes { typedef std::unique_ptr&lt;AttrBase&gt; AttrPtr; typedef std::map&lt;AttrTag, AttrPtr&gt; AttrMap; AttrMap attributes; template &lt;AttrTag TAG&gt; typename Attr&lt;TAG&gt;::value_type get_attr () const { AttrMap::const_iterator i = attributes.find(TAG); if (i != attributes.end()) return i-&gt;second-&gt;attr_cast&lt;TAG&gt;()-&gt;value; return Attr&lt;TAG&gt;::default_value; } template &lt;AttrTag TAG&gt; void set_attr (typename Attr&lt;TAG&gt;::value_type value) { attributes[TAG] = AttrPtr(new Attr&lt;TAG&gt;(value)); } bool has_attr (AttrTag t) const { return attributes.find(t) != attributes.end(); } }; </code></pre> <p>And it would be used like this:</p> <pre><code>Attributes attrs; attrs-&gt;set_attr&lt;AT_Gold&gt;(100); //... ADTBattleCharacter(attrs); //... unsigned short g = attrs-&gt;get_attr&lt;AT_Gold&gt;(); </code></pre> <p>The attributes would come off the <code>AttrBase</code> class that would know how to delegate to the actual attribute.</p> <pre><code>template &lt;AttrTag&gt; struct Attr; struct AttrBase { virtual ~AttrBase () {} template &lt;AttrTag TAG&gt; Attr&lt;TAG&gt; * attr_cast () { return dynamic_cast&lt;Attr&lt;TAG&gt; *&gt;(this); } }; </code></pre> <p>And attributes would be created from specializing an <code>Attr</code> template that inherits from <code>AttrBase</code>.</p> <pre><code>template &lt;AttrTag TAG&gt; struct Attr : public AttrBase { typedef unsigned char value_type; enum { default_value = 0 }; value_type value; Attr (value_type v) : value(v) {} }; template &lt;&gt; struct Attr&lt;AT_Name&gt; : public AttrBase { typedef std::string value_type; static std::string default_value; value_type value; Attr (value_type v) : value(v) {} }; template &lt;&gt; struct Attr&lt;AT_Gold&gt; : public AttrBase { typedef unsigned short value_type; enum { default_value = 1 }; value_type value; Attr (value_type v) : value(v) {} }; </code></pre> <p>This allows new attributes to be incrementally added without increasing the complexity of your constructor. In addition, the same collection of attributes could be passed to different entities, and each could react to only those attributes of interest to them. Only a subset of attributes need be set. The presence of an attribute can be tested, or a default value can be used. If you want to add and remove dynamic attributes, the container could be extended to do so by adding an additional map to hold them.</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.
    3. 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