Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Creating a property helper class that must be instanciated as a member of the class you want to add property on is a bad idea, since you'll have the cost of the property members for all the instances of this class.</p> <p>A solution that offers a "property" mechanism close to what other languages offer can be made available in C++ using something like what I describe later.</p> <p>The only limitation being that you access the property using </p> <p>instance.property(); // to get</p> <p>and</p> <p>instance.property() = 42; // to set</p> <pre><code>#include &lt;iostream&gt; #include &lt;string&gt; using namespace std; // ------------------------------------------------------------------ #define PROPERTY_GET_SET(CLASS, NAME, TYPE) GetSetProperty&lt;CLASS, TYPE&gt; NAME() { return GetSetProperty&lt;CLASS, TYPE&gt;(this, &amp;CLASS::get_##NAME, &amp;CLASS::set_##NAME); } #define PROPERTY_GET(CLASS, NAME, TYPE) GetProperty&lt;CLASS, TYPE&gt; NAME() { return GetProperty&lt;CLASS, TYPE&gt;(this, &amp;CLASS::get_##NAME); } #define PROPERTY_SET(CLASS, NAME, TYPE) SetProperty&lt;CLASS, TYPE&gt; NAME() { return SetProperty&lt;CLASS, TYPE&gt;(this, &amp;CLASS::set_##NAME); } template &lt;typename CLASS, typename TYPE&gt; struct GetSetProperty { typedef TYPE (CLASS::*Getter_t)() const; typedef void (CLASS::*Setter_t)(TYPE); GetSetProperty(CLASS* instance, Getter_t getter, Setter_t setter) : m_instance(instance), m_getter(getter), m_setter(setter) {} operator TYPE() const { return (this-&gt;m_instance-&gt;*this-&gt;m_getter)(); } GetSetProperty&lt;CLASS, TYPE&gt;&amp; operator=(TYPE value) { (this-&gt;m_instance-&gt;*this-&gt;m_setter)(value); return *this; } CLASS* const m_instance; const Getter_t m_getter; const Setter_t m_setter; }; template &lt;typename CLASS, typename TYPE&gt; struct GetProperty { typedef TYPE (CLASS::*Getter_t)() const; GetProperty(CLASS* instance, Getter_t getter) : m_instance(instance), m_getter(getter) {} operator TYPE() const { return (this-&gt;m_instance-&gt;*this-&gt;m_getter)(); } CLASS* const m_instance; const Getter_t m_getter; }; template &lt;typename CLASS, typename TYPE&gt; struct SetProperty { typedef void (CLASS::*Setter_t)(TYPE); SetProperty(CLASS* instance, Setter_t setter) : m_instance(instance), m_setter(setter) {} SetProperty&lt;CLASS, TYPE&gt;&amp; operator=(TYPE value) { (this-&gt;m_instance-&gt;*this-&gt;m_setter)(value); return *this; } CLASS* const m_instance; const Setter_t m_setter; }; template &lt;typename CLASS, typename TYPE&gt; ostream&amp; operator&lt;&lt;(ostream&amp; ostr, const GetSetProperty&lt;CLASS, TYPE&gt;&amp; p) { ostr &lt;&lt; (p.m_instance-&gt;*p.m_getter)(); return ostr; } template &lt;typename CLASS, typename TYPE&gt; ostream&amp; operator&lt;&lt;(ostream&amp; ostr, const GetProperty&lt;CLASS, TYPE&gt;&amp; p) { ostr &lt;&lt; (p.m_instance-&gt;*p.m_getter)(); return ostr; } // ------------------------------------------------------------------ class Dummy { public: Dummy() : m_value1(42) {} PROPERTY_GET_SET(Dummy, Value1, int); PROPERTY_GET_SET(Dummy, Value2, const string&amp;); protected: virtual int get_Value1() const { return this-&gt;m_value1; } virtual void set_Value1(int value) { this-&gt;m_value1 = value; } virtual const string&amp; get_Value2() const { return this-&gt;m_value2; } virtual void set_Value2(const string&amp; value) { this-&gt;m_value2 = value; } private: int m_value1; string m_value2; }; int main(int argc, char* argv[]) { Dummy d; cout &lt;&lt; d.Value1() &lt;&lt; endl; d.Value1() = 3; cout &lt;&lt; d.Value1() &lt;&lt; endl; cout &lt;&lt; d.Value2() &lt;&lt; endl; d.Value2() = "test"; cout &lt;&lt; d.Value2() &lt;&lt; endl; return 0; } // ------------------------------------------------------------------ </code></pre>
    singulars
    1. This table or related slice is empty.
    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. 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