    <rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:admin="http://webns.net/mvcb/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:content="http://purl.org/rss/1.0/modules/content/">
     <channel>
        <title>ACCU  :: C++ Properties - a Library Solution</title>
        <link>https://members.accu.org/index.php/articles/255</link>
        <description>Professionalism in Programming</description>
        <dc:language>en-us</dc:language> 
        <dc:creator>Administrator</dc:creator> 
        <admin:generatorAgent rdf:resource="http://www.xaraya.org" /> 
        <admin:errorReportsTo rdf:resource="mailto:webeditor@accu.org" />
       <sy:updatePeriod>hourly</sy:updatePeriod>
       <sy:updateFrequency>1</sy:updateFrequency>
       <docs>http://backend.userland.com/rss</docs>




<div class="xar-mod-head"><span class="xar-mod-title">Programming Topics + Overload Journal #65 - Feb 2005</span></div>

<table border="0" cellpadding="1" cellspacing="0">
    <tbody>
    <tr>
        <td valign="top">
            Browse in :
       </td>
       <td valign="top">

                                            <a href="https://members.accu.org/index.php/articles/">All</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c13/">Topics</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c65/">Programming</a>
<br />

                                            <a href="https://members.accu.org/index.php/articles/">All</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c76/">Journals</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c78/">Overload</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c147/">65</a>
<br />

                                            <a href="https://members.accu.org/index.php/articles/c65-147/">Any of these categories</a>

                    -                        <a href="https://members.accu.org/index.php/articles/c65+147/">All of these categories</a>
<br />
</td>
   </tr>
   </tbody>
</table>




<div class="xar-error">
   <p>
 <strong>Note:</strong> when you create a new publication type,
the articles module will automatically use the templates
<em>user-display-[publicationtype].xt</em>
and <em>user-summary-[publicationtype].xt</em>.
If those templates do not exist when you try to preview or display a new article,
you'll get this warning :-)  Please place your own templates in themes/<em>yourtheme</em>/modules/articles . The templates will get the extension .xt there. </p>
</div>
<div class="xar-norm xar-standard-box-padding">
   <h1><strong>Title:</strong>&nbsp;C++ Properties - a Library Solution</h1>
<p><strong>Author:</strong>&nbsp;</p>
<p>
<strong>Date:</strong> 12 February 2005 16:35:57 +00:00 or Sat, 12 February 2005 16:35:57 +00:00</p>
<p><strong>Summary:</strong>&nbsp;</p>
<p><strong>Body:</strong>&nbsp;<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e16" id="d0e16"></a></h2>
</div>
<p>Properties are a feature of a number of programming languages -
Visual Basic and C# are two of them. While they are not part of
standard C++, they have been implemented in C++ for the CLI
(popularly known as .Net) environment and Borland C++ Builder,
which comes with a library of useful components which make heavy
use of properties in their interfaces. And when programmers are
asked their ideas for extensions to C++, properties are a popular
request. [<a href="#Wiegley">Wiegley</a>,<a href=
"#Vandevoorde">Vandevoorde</a>]</p>
<p>So what is a property? The C++/CLI draft spec says,
&quot;<span class="quote">A property is a member that behaves as if it
were a field... Properties are used to implement data hiding within
the class itself.</span>&quot; In the class declaration, properties must
be declared with a special keyword so the compiler knows to add
appropriate magic:</p>
<pre class="programlisting">
class point {
private:
  int Xor;
  int Yor;
public:
  property int X {
    int get() {
      return Xor;
    }
    void set(int value) {
      Xor = value;
    }
  }
  ...
};

point p; p.X = 25;
</pre>
<p>In application code, properties look like ordinary data members
of a class; their value can be read from and assigned to with a
simple = sign. But in fact they are only pseudo-data members. Any
such reference implicitly invokes an accessor function call &quot;under
the covers&quot; and certain language features don't work with
properties. One example is taking the address of a data member and
assigning it to a pointer-to-member.</p>
<p>Let me say up front that I dislike this style of programming
with properties. The subtle advantage of &quot;hiding&quot; a private data
member by treating it as a public data member escapes me. And from
the object-oriented-design point of view, I think they are highly
suspect. One of the fundamental principles of OO design is that
behaviour should be visible; state should not. To conceal behaviour
by masquerading it as a data member is just encouraging bad
habits.</p>
<p>Properties are syntactic saccharine for getter and setter member
functions for individual fields in a class. Of course, in the quest
for good design, replacing a public data member with simple get/set
functions for that data member does not achieve a large increase in
abstraction. A function-call syntax which does not overtly refer to
manipulating data members may lead to a cleaner interface. It
allows the possibility that some &quot;data members&quot; may be computed at
runtime rather than stored. An overwhelming majority of books on OO
design recommend thinking in terms of objects' behaviour, while
hiding their state. Let us encourage good habits, not bad ones.</p>
<p>UK C++ panel member Alisdair Meredith, with almost a decade's
daily experience using the Borland VCL properties, had these
comments:</p>
<div class="blockquote">
<blockquote class="blockquote">
<p>Properties work fantastically well in RAD development where you
want interactive tools beyond a simple source code editor. For all
they appear glorified get/set syntax, they make the life of the
component writer much simpler. There are no strange coding
conventions to follow so that things magically work, and a lot of
boilerplate code vanishes. From this perspective they are most
definitely A Good Thing&trade;.</p>
<p>Of course the property concept goes way beyond simply supporting
GUI tools, and that is where the slippery slope begins...</p>
<p>If functional programming is 'programming without side effects',
property oriented programming is the other extreme. Everything
relies on side effects that occur as you update state. For example:
you have a <tt class="varname">Left</tt> property in your GUI
editor to determine position of a control. How would you move this
control at runtime? Traditionally we might write some kind of
<tt class="function">Move()</tt> function, but now we can set the
Left property instead and that will somehow magically move the
control on the form as a side-effect, and maybe trigger other
events with callbacks into user code as a consequence.</p>
<p>Experience shows that people prefer to update the <tt class=
"varname">Left</tt> property rather than look for some other
function. After all, that is how you would perform the same task at
design/compile time. Generally, code becomes manipulating
properties (and expecting the side effects) rather than making
explicit function calls. Again, this is the 'minimum interface'
principle so that there is one and only one simple way of achieving
a given result. Typically, the <tt class="function">Move()</tt>
function is never written, and this reinforces the programming
style.</p>
<p>As we move beyond the GUI-tools arena, I find the property
syntax becomes more and more confusing. I can no longer know by
simple inspection of a function implementation if I can take the
address of everything used as a variable, or even pass them by
reference. This only gets worse when templates enter the mix.</p>
</blockquote>
</div>
<p>And the problem becomes worse yet when developers become fond of
using write-only properties - values which can be set to achieve
the side effect, but can never be queried.</p>
<p>The one-sentence summary of his experience is that using
properties in non-GUI classes did not help productivity:
&quot;<span class="quote">Properties made our code easier to write, but
immensely more difficult to maintain.</span>&quot; My own experience in
trying to debug code with properties bears this out. While stepping
through some code to look for leaks of memory and COM interfaces, I
was examining all variables by hovering the mouse over them.
Multiple hovers over the same variable (or what appeared to be a
simple variable) showed up a data structure with different values
each time, because the underlying property function was creating an
additional COM interface with each access.</p>
<p>My impression is that the main benefit envisioned for properties
is not their syntactic sleight-of-hand but (1) their ability to be
discovered through introspection/reflection and manipulated
non-programmatically by some sort of Rapid Application Development
tool, and (2) their ability to be stored (I think &quot;pickled&quot; is the
term used with Java Beans) in this configured state, so that they
can be loaded at runtime, already configured. [1] appears to take
for granted that these features should come as a package, if
standard C++ were to be extended to embrace properties.</p>
<p>However I might feel about using properties, I have to recognise
that many people do find them useful, at least for certain types of
applications. For people who do like this style of programming, at
least some of the benefits can be achieved through library classes
without changing the C++ language and compilers. The accompanying
sample code defines some utility class templates which may be used
as members of domain classes:</p>
<div class="variablelist">
<dl>
<dt><span class="term">Property</span></dt>
<dd>
<p>a read-write property with data store and automatically
generated get/set functions. This is what C++/CLI calls a trivial
scalar property.</p>
</dd>
<dt><span class="term">ROProperty</span></dt>
<dd>
<p>a read-only property calling a user-defined getter.</p>
</dd>
<dt><span class="term">WOProperty</span></dt>
<dd>
<p>a write-only property calling a user-defined setter.</p>
</dd>
<dt><span class="term">RWProperty</span></dt>
<dd>
<p>a read-write property which invokes user-defined functions.</p>
</dd>
<dt><span class="term">IndexedProperty</span></dt>
<dd>
<p>a read-write named property with indexed access to own data
store.</p>
</dd>
</dl>
</div>
<p>For programmer convenience these classes offer three redundant
syntaxes for accessing their data members (or apparent data members
- properties need not have real storage behind them):</p>
<div class="itemizedlist">
<ul type="disc">
<li>
<p>function call syntax</p>
</li>
<li>
<p><tt class="function">get</tt>/<tt class="function">set</tt>
functions</p>
</li>
<li>
<p><tt class="methodname">operator = (T)</tt> and <tt class=
"methodname">operator T()</tt> for assignment to and from
properties.</p>
</li>
</ul>
</div>
<p>The read-only and write-only property classes implement only the
accessors appropriate to their semantics, but for compatibility
with C++/CLI they do reserve (unimplemented) the unnecessary
<tt class="function">get</tt> or <tt class="function">set</tt>
identifier.</p>
<p>Instances of the utility templates as outlined in this paper do
have an address, they have a type for template deduction, and they
can be used in a chain of assignments. They can also be used with
today's compilers and debuggers. If someone brings forward a RAD
tool to read and manipulate properties through metadata, then a
&quot;property&quot; modifier or some other marker for the tool could be
added to their declaration to help in generating the metadata.</p>
<p>This technique, described in its basic form in <i class=
"citetitle">C++ Report</i> back in 1995<sup>[<a name="d0e143" href=
"#ftn.d0e143" id="d0e143">1</a>]</sup>, seems at least as
convenient, and produces as economical source code, as most uses of
properties. The basic assignment and return functions can be
inlined, and therefore should be efficient. In order to support
chaining, the setter functions return their new value, but for
complete compatibility with C++/CLI they should have a void return
type.</p>
<p>One objection to these that has been raised is that CLI
properties allegedly take up no space inside a class, whereas a C++
subobject cannot have a size of 0 (ignoring certain clever
optimizations). On the other hand, I expect that most useful
properties will need some way to preserve state between <tt class=
"function">set</tt> and <tt class="function">get</tt>, and that has
to take up space somewhere. The size of <tt class=
"classname">Property&lt;T&gt;</tt> takes up as much space as a
single object of its template parameter, while the other three hold
only a single pointer to an implementation object. Note that the
<tt class="classname">Object</tt> and member function template
parameters do not have to refer to the containing object, though
that is likely to be the most common usage. They could delegate the
processing to an external or nested helper class. The choice of
implementation object (though not its type or member functions) can
even be changed dynamically, and several objects could share a
single implementation object.</p>
<p>The biggest inconvenience to these classes that I perceive is
that all but the simplest <tt class=
"classname">Property&lt;T&gt;</tt> instances need to be initialized
at runtime with the address of their implementation object (usually
the containing class). A smaller inconvenience is that using them
on the right hand side of an assignment invokes a user-defined
conversion, which could affect overload resolution and a sequence
of conversions.</p>
<p>One of the features of C++/CLI properties is that they can be
declared as virtual or pure virtual, for polymorphic overriding by
derived classes. This obviously is not possible with data member
declarations. But if the implementation object (which usually means
the containing object) is itself polymorphic and the designated
member functions are virtual, then the property will behave in a
polymorphic fashion.</p>
<p>The C++/CLI feature of default (nameless) indexed properties can
be simulated with a member <tt class="methodname">operator []</tt>
(except that in C++/CLI indexes can take multiple arguments, but
there is a separate proposal for C++ to allow comma-separated
arguments inside square brackets).</p>
<p>Aside from matters of stylistic preference, I can see two
possible scenarios in which these classes might be useful. One
scenario would be in source code which needs to be portable between
C++/CLI and standard C++ environments. Using the <tt class=
"classname">Property&lt;T&gt;</tt> templates on the standard C++
side could compensate for a lack of compiler support for
properties.</p>
<p>The second scenario would be for migrating code which uses
public data members to a more encapsulated style. The class
definitions could be rewritten to use the <tt class=
"classname">Property&lt;T&gt;</tt> templates, while client code
need not be rewritten, only recompiled.</p>
<p>A brief sample program (at the end of this article) shows the
utility classes in use. As it illustrates three different styles of
setting and getting a property value, the expected output is
this:</p>
<pre class="programlisting">
Name = Pinkie Platypus
Name = Kuddly Koala
Name = Willie Wombat

ID = 12345678
ID = 9999
ID = 42

Children = 42
Children = 42
Children = 42

WO function myClass::addWeight called with
                                value 2.71828
WO function myClass::addWeight called with
                                value 3.14159
WO function myClass::addWeight called with
                                value 1.61803
Secretkey = *****
Secretkey = !!!!!
Secretkey = ?????

Convenor = Herb
Minutes = Daveed
Coffee = Francis
</pre>
<div class="sidebar">
<p class="title c2">Initialisation Methods for Properties</p>
<p>Overload Technical Reviewer Phil Bass raised this question while
reviewing the article for publication:</p>
<div class="blockquote">
<blockquote class="blockquote">
<p>The ROProperty, WOProperty and RWProperty classes provide a
function call operator for initialisation. Why don't they have
constructors instead?</p>
</blockquote>
</div>
<p>After looking over the code now (it was originally written last
April) I have added a default constructor which makes sure the
pointers are set to 0 for safety. But they still need to have an
initialisation function. Initialising them, either with a named
function or an overloaded function call operator, gives runtime
flexibility. These are the benefits that occur to me:</p>
<div class="itemizedlist">
<ul type="disc">
<li>
<p>If the implementation object were initialised in a constructor,
it would create a dependency on the prior existence of the
implementation object. In a complex application where such
dependencies might be chained or even circular, this would be a
nuisance.</p>
</li>
<li>
<p>The implementation object can be rebound. I don't know of any
specific use cases that would drive this, but the capability falls
out of doing it this way and might prove useful.</p>
</li>
<li>
<p>One implementation object could serve several different
instances of objects with a property. Again, it just falls out. If
pressed to come up with a use case, I would look for a situation
where the 'property' has to be extracted from some heavyweight
situation - a database, a large table in memory, a remote procedure
call, or some kind of bottleneck where localised optimisations like
caching could make a difference. This encapsulates the resource
issues and shares the benefits around.</p>
</li>
<li>
<p>Since the function call operator (or some initialisation
function) has to exist anyway, adding a constructor call which
takes a value might confuse some programmers as to which they were
calling. It wouldn't confuse the compiler - <tt class=
"methodname">NumberOfChildren(p)</tt> in an initialiser list for
<tt class="classname">myClass</tt> would invoke the constructor,
whereas <tt class="methodname">NumberOfChildren(this)</tt> inside a
<tt class="classname">myClass</tt> constructor is calling the
<tt class="methodname">operator()()</tt> - but they look alike in
code and many people are kind of vague about such details (which is
a reason why many people avoid function objects).</p>
</li>
<li>
<p>The combination of the first and last points above brings us to
the REAL reason why we don't initialise it in a constructor: the
most common use case is likely to be that the enclosing object
exposing the property provides its own implementation for it. If we
need to initialise a data member with a constructor, we would
naturally expect to do so in the initialiser list of the enclosing
object's constructor, like this:</p>
<pre class="programlisting">
myClass() : NumberOfChildren(this),
            WeightedValue(this),
            Secretkey(this) {}
</pre></li>
</ul>
</div>
<p>But as the <tt class="classname">myClass</tt> instance doesn't
really exist before its constructor is entered, using its this
pointer as an argument to the member constructors in the
initialiser list seems, well, dubious. Of my three test compilers
only MSVC++ gave a warning that &quot;the this pointer is only valid
within nonstatic member functions.&quot; All three compiled and ran this
program, but I wouldn't want to rely on that as proof of
correctness. I'm afraid I did not devise a stress test involving a
polymorphic hierarchy to see how far I could push it before
something broke.</p>
<p>I did think hard about what syntax in a property class
constructor would be able to deduce the address of the property's
enclosing object as a default - that would be really useful! - but
concluded there is no way to say that in C++. So, since the user of
the class will have to initialise it at some point, not having a
constructor means that initialisation has to go into the body of
the enclosing object's constructor rather than its initialiser
list. I opted for the function call syntax as more concise than a
named member function.</p>
<p>I admit that all this was written as a proof-of-concept rather
than well-tested production code. For industrial-strength use, one
needs to envision pathological scenarios that might arise. If the
overloaded setter using function-call syntax ever takes a parameter
of the same type as the implementation object (value has type
<tt class="type">Object *</tt>), there is going to be an ambiguity
with the initialiser; for this situation the solution is a named
initialiser member function and/or a named <tt class=
"function">set()</tt> function. Another low-probability scenario
(which means one that is guaranteed to bite you sooner or later) is
using an external implementation object which is itself a
<tt class="literal">const</tt> instance. The workaround for this
would be another, slightly different, utility class template
wrapping a <tt class="literal">const Object * my_object;</tt></p>
<p>One of the advantages of implementing properties as library
classes instead of a built-in language feature is that the
programmer can vary or extend them as needed!</p>
</div>
<pre class="programlisting">
// Some utility templates for emulating
// properties - preferring a library solution
// to a new language feature
// Each property has three sets of redundant
// acccessors:
// 1. function call syntax
// 2. get() and set() functions
// 3. overloaded operator =

// a read-write property with data store and
// automatically generated get/set functions.
// this is what C++/CLI calls a trivial scalar
// property
template &lt;class T&gt;
class Property {
  T data;
public:

  // access with function call syntax
  Property() : data() { }
  T operator()() const {
    return data;
  }
  T operator()(T const &amp; value) {
    data = value;
    return data;
  }

  // access with get()/set() syntax
  T get() const {
    return data;
  }
  T set(T const &amp; value) {
    data = value;
    return data;
  }

  // access with '=' sign
  // in an industrial-strength library,
  // specializations for appropriate types
  // might choose to add combined operators
  // like +=, etc.
  operator T() const {
    return data;
  }
  T operator=(T const &amp; value) {
    data = value;
    return data;
  }
  typedef T value_type;
            // might be useful for template
            // deductions
};

// a read-only property calling a
// user-defined getter
template &lt;typename T, typename Object,
          T (Object::*real_getter)()&gt;
class ROProperty {
  Object * my_object;
public:
  ROProperty() : my_object(0) {}
  ROProperty(Object * me = 0)
               : my_object(me) {}

  // this function must be called by the
  // containing class, normally in a
  // constructor, to initialize the
  // ROProperty so it knows where its
  // real implementation code can be
  // found.
  // obj is usually the containing
  // class, but need not be; it could be a
  // special implementation object.
  void operator()(Object * obj) {
    my_object = obj;
  }

  // function call syntax
  T operator()() const {
    return (my_object-&gt;*real_getter)();
  }

  // get/set syntax
  T get() const {
    return (my_object-&gt;*real_getter)();
  }
  void set(T const &amp; value);
            // reserved but not implemented,
            // per C++/CLI

  // use on rhs of '='
  operator T() const {
    return (my_object-&gt;*real_getter)();
  }

  typedef T value_type;
            // might be useful for template
            // deductions
};

// a write-only property calling a
// user-defined setter
template &lt;class T, class Object,
          T (Object::*real_setter)(T const &amp;)&gt;
class WOProperty {
  Object * my_object;
public:
  WOProperty() : my_object(0) {}
  WOProperty(Object * me = 0)
               : my_object(me) {}

  // this function must be called by the
  // containing class, normally in a
  // constructor, to initialize the
  // WOProperty so it knows where its real
  // implementation code can be found
  void operator()(Object * obj) {
    my_object = obj;
  }
  // function call syntax
  T operator()(T const &amp; value) {
    return (my_object-&gt;*real_setter)(value);
  }
  // get/set syntax
  T get() const;
            // reserved but not implemented,
            // per C++/CLI
  T set(T const &amp; value) {
    return (my_object-&gt;*real_setter)(value);
  }

  // access with '=' sign
  T operator=(T const &amp; value) {
    return (my_object-&gt;*real_setter)(value);
  }

  typedef T value_type;
            // might be useful for template
            // deductions
};

// a read-write property which invokes
// user-defined functions
template &lt;class T,
          class Object,
          T (Object::*real_getter)(),
          T (Object::*real_setter)(T const &amp;)&gt;
class RWProperty {
  Object * my_object;
public:
  RWProperty() : my_object(0) {}
  RWProperty(Object * me = 0)
               : my_object(me) {}

  // this function must be called by the
  // containing class, normally in a
  // constructor, to initialize the
  // ROProperty so it knows where its
  // real implementation code can be
  // found
  void operator()(Object * obj) {
    my_object = obj;
  }

  // function call syntax
  T operator()() const {
    return (my_object-&gt;*real_getter)();
  }
  T operator()(T const &amp; value) {
    return (my_object-&gt;*real_setter)(value);
  }

  // get/set syntax
  T get() const {
    return (my_object-&gt;*real_getter)();
  }
  T set(T const &amp; value) {
    return (my_object-&gt;*real_setter)(value);
  }
  // access with '=' sign
  operator T() const {
    return (my_object-&gt;*real_getter)();
  }
  T operator=(T const &amp; value) {
    return (my_object-&gt;*real_setter)(value);
  }

  typedef T value_type;
            // might be useful for template
            // deductions
};

// a read/write property providing indexed
// access.
// this class simply encapsulates a std::map
// and changes its interface to functions
// consistent with the other property&lt;&gt;
// classes.
// note that the interface combines certain
// limitations of std::map with
// some others from indexed properties as
// I understand them.
// an example of the first is that
// operator[] on a map will insert a
// key/value pair if it isn't already there.
// A consequence of this is that it can't
// be a const member function (and therefore
// you cannot access a const map using
// operator [].)
// an example of the second is that indexed
// properties do not appear to have any
// facility for erasing key/value pairs
// from the container.
// C++/CLI properties can have
// multi-dimensional indexes: prop[2,3].
// This is not allowed by the current rules
// of standard C++
#include &lt;map&gt;
template &lt;class Key,
          class T,
          class Compare = std::less&lt;Key&gt;,
          class Allocator
               = std::allocator&lt;std::pair&lt;
                           const Key, T&gt; &gt; &gt;
class IndexedProperty {
  std::map&lt;Key, T, Compare,
           Allocator&gt; data;
  typedef typename std::map&lt;Key, T, Compare,
                        Allocator&gt;::iterator
          map_iterator;
public:

  // function call syntax
  T operator()(Key const &amp; key) {
    std::pair&lt;map_iterator, bool&gt; result;
    result
      = data.insert(std::make_pair(key, T()));
    return (*result.first).second;
  }
  T operator()(Key const &amp; key,
               T const &amp; t) {
    std::pair&lt;map_iterator, bool&gt; result;
    result
      = data.insert(std::make_pair(key, t));
    return (*result.first).second;
  }

  // get/set syntax
  T get_Item(Key const &amp; key) {
    std::pair&lt;map_iterator, bool&gt; result;
    result
      = data.insert(std::make_pair(key, T()));
    return (*result.first).second;
  }
  T set_Item(Key const &amp; key,
             T const &amp; t) {
    std::pair&lt;map_iterator, bool&gt; result;
    result
      = data.insert(std::make_pair(key, t));
    return (*result.first).second;
  }

  // operator [] syntax
  T&amp; operator[](Key const &amp; key) {
    return (*((data.insert(make_pair(
                   key, T()))).first)).second;
  }
};


// =================================
// and this shows how Properties are
// accessed:
// =================================

#include &lt;string&gt;
#include &lt;iostream&gt;

class myClass {
private:
  Property&lt;std::string&gt; secretkey_;

  // --user-defined implementation functions--
  // in order to use these as parameters,
  // the compiler needs to see them
  // before they are used as template
  // arguments. It is possible to get rid
  // of this order dependency by writing
  // the templates with slight
  // differences, but then the program
  // must initialize them with the
  // function addresses at run time.

  // myKids is the real get function
  // supporting NumberOfChildren
  // property
  int myKids() {
    return 42;
  }
  // addWeight is the real set function
  // supporting WeightedValue property
  float addWeight(float const &amp; value) {
    std::cout &lt;&lt; &quot;WO function &quot;
              &lt;&lt; &quot;myClass::addWeight &quot;
              &lt;&lt; &quot;called with value &quot;
              &lt;&lt; value
              &lt;&lt; std::endl;
    return value;
  }
  // setSecretkey and getSecretkey support
  // the Secretkey property
  std::string setSecretkey(
                     const std::string&amp; key) {

    // extra processing steps here

    return secretkey_(key);
  }
  std::string getSecretkey() {

    // extra processing steps here

    return secretkey_();
  }

public:
  // Name and ID are read-write properties
  // with automatic data store
  Property&lt;std::string&gt; Name;
  Property&lt;long&gt; ID;

  // Number_of_children is a read-only
  // property
  ROProperty&lt;int, myClass,
           &amp;myClass::myKids&gt; NumberOfChildren;

  // WeightedValue is a write-only
  // property
  WOProperty&lt;float, myClass,
           &amp;myClass::addWeight&gt; WeightedValue;

  // Secretkey is a read-write property
  // calling user-defined functions
  RWProperty&lt;std::string, myClass,
           &amp;myClass::getSecretkey,
           &amp;myClass::setSecretkey&gt; Secretkey;

  IndexedProperty&lt;std::string,
                  std::string&gt; Assignments;

  // constructor for this myClass object
  // must notify member properties
  // what object they belong to
  myClass() {
    NumberOfChildren(this);
    WeightedValue(this);
    Secretkey(this);
  }
};
int main() {
  myClass thing;

  // Property&lt;&gt; members can be accessed
  // with function syntax ...
  thing.Name(&quot;Pinkie Platypus&quot;);
  std::string s1 = thing.Name();
  std::cout &lt;&lt; &quot;Name = &quot;
            &lt;&lt; s1
            &lt;&lt; std::endl;

  // ... or with set/get syntax ...
  thing.Name.set(&quot;Kuddly Koala&quot;);
  s1 = thing.Name.get();
  std::cout &lt;&lt; &quot;Name = &quot;
            &lt;&lt; s1
            &lt;&lt; std::endl;

  // ... or with the assignment operator
  thing.Name = &quot;Willie Wombat&quot;;
  s1 = thing.Name;
  std::cout &lt;&lt; &quot;Name = &quot;
            &lt;&lt; s1
            &lt;&lt; std::endl;
  std::cout &lt;&lt; std::endl;

  // The same applies to Property&lt;&gt; members
  // wrapping different data types
  thing.ID(12345678);
  long id = thing.ID();
  std::cout &lt;&lt; &quot;ID = &quot;
            &lt;&lt; id
            &lt;&lt; std::endl;

  thing.ID.set(9999);
  id = thing.ID.get();
  std::cout &lt;&lt; &quot;ID = &quot;
            &lt;&lt; id
            &lt;&lt; std::endl;

  thing.ID = 42;
  id = thing.ID;
  std::cout &lt;&lt; &quot;ID = &quot;
            &lt;&lt; id
            &lt;&lt; std::endl;
  std::cout &lt;&lt; std::endl;

  // And to ROProperty&lt;&gt; members
  int brats = thing.NumberOfChildren();
  std::cout &lt;&lt; &quot;Children = &quot;
            &lt;&lt; brats
            &lt;&lt; std::endl;

  brats = thing.NumberOfChildren.get();
  std::cout &lt;&lt; &quot;Children = &quot;
            &lt;&lt; brats
            &lt;&lt; std::endl;

  brats = thing.NumberOfChildren;
  std::cout &lt;&lt; &quot;Children = &quot;
            &lt;&lt; brats
            &lt;&lt; std::endl;
  std::cout &lt;&lt; std::endl;

  // And WOProperty&lt;&gt; members
  thing.WeightedValue(2.71828);

  thing.WeightedValue.set(3.14159);

  thing.WeightedValue = 1.618034;
  std::cout &lt;&lt; std::endl;

  // and RWProperty&lt;&gt; members
  thing.Secretkey(&quot;*****&quot;);
  std::string key = thing.Secretkey();
  std::cout &lt;&lt; &quot;Secretkey = &quot;
            &lt;&lt; key
            &lt;&lt; std::endl;

  thing.Secretkey.set(&quot;!!!!!&quot;);
  key = thing.Secretkey.get();
  std::cout &lt;&lt; &quot;Secretkey = &quot;
            &lt;&lt; key
            &lt;&lt; std::endl;

  thing.Secretkey = &quot;?????&quot;;
  key = thing.Secretkey;
  std::cout &lt;&lt; &quot;Secretkey = &quot;
            &lt;&lt; key
            &lt;&lt; std::endl;
  std::cout &lt;&lt; std::endl;

  // and IndexedProperty&lt;&gt; members.
  // Multiple indices in square brackets
  // not supported yet
  thing.Assignments(&quot;Convenor&quot;,
                    &quot;Herb&quot;);
  std::string job = thing.Assignments(
                                 &quot;Convenor&quot;);
  std::cout &lt;&lt; &quot;Convenor = &quot;
            &lt;&lt; job
            &lt;&lt; std::endl;

  thing.Assignments.set_Item(&quot;Minutes&quot;,
                             &quot;Daveed&quot;);
  job = thing.Assignments.get_Item(
                                 &quot;Minutes&quot;);
  std::cout &lt;&lt; &quot;Minutes = &quot;
            &lt;&lt; job
            &lt;&lt; std::endl;

  thing.Assignments[&quot;Coffee&quot;] = &quot;Francis&quot;;
  job = thing.Assignments[&quot;Coffee&quot;];
  std::cout &lt;&lt; &quot;Coffee = &quot;
            &lt;&lt; job
            &lt;&lt; std::endl;
  std::cout &lt;&lt; std::endl;

  return 0;
}
</pre></div>
<div class="bibliography">
<div class="titlepage">
<h2><a name="d0e254" id="d0e254"></a>References</h2>
</div>
<div class="bibliomixed"><a name="Wiegley" id="Wiegley"></a>
<p class="bibliomixed">[Wiegley] John Wiegley, <span class=
"citetitle"><i class="citetitle">PME: Properties, Methods, and
Events</i></span>. <span class="bibliomisc"><a href=
"http://www.open-std.org/jtc1/sc22/wg21/docs/%20papers/2002/n1384.pdf"
target="_top">http://www.open-std.org/jtc1/sc22/wg21/docs/
papers/2002/n1384.pdf</a></span></p>
</div>
<div class="bibliomixed"><a name="Vandevoorde" id=
"Vandevoorde"></a>
<p class="bibliomixed">[Vandevoorde] David Vandevoorde,
<span class="citetitle"><i class="citetitle">C++/CLI
Properties</i></span>. <span class="bibliomisc"><a href=
"http://www.open-std.org/jtc1/sc22/wg21/docs/%20papers/2004/n1600.html"
target="_top">http://www.open-std.org/jtc1/sc22/wg21/docs/
papers/2004/n1600.html</a></span></p>
</div>
</div>
<div class="footnotes"><br>
<hr class="c3" width="100">
<div class="footnote">
<p><sup>[<a name="ftn.d0e143" href="#d0e143" id=
"ftn.d0e143">1</a>]</sup> Unfortunately I don't have a more exact
reference to hand.</p>
</div>
</div>
</p>
<p><strong>Notes:</strong>&nbsp;</p>
<p><em>More fields may be available via dynamicdata ..</em></p>
</div>
</channel>
</rss>
