    <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  :: Metaclasses and Reflection in C++ - Part 2</title>
        <link>https://members.accu.org/index.php/articles/421</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 #46 - Dec 2001</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/c158/">46</a>
<br />

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

                    -                        <a href="https://members.accu.org/index.php/articles/c65+158/">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;Metaclasses and Reflection in C++ - Part 2</h1>
<p><strong>Author:</strong>&nbsp;</p>
<p>
<strong>Date:</strong> 26 December 2001 16:46:08 +00:00 or Wed, 26 December 2001 16:46:08 +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="d0e18" id="d0e18"></a></h2>
</div>
<p>In an article published in Overload 45 I described the design
and implementation of a meta-object layer for C++, MOP. Definitions
were provided for both metaclasses and metaobjects. This article
continues that discussion by demonstrating how they can be used to
solve the design problems found in an Internet bookshop example.
Susan, the manager of the store, requires a highly dynamic system
to allow the business flexibility she requires to be successful.
Using a metaclass her products would be modelled thus:</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e22" id="d0e22"></a>Now the MOP is
complete. Let's use it:</h2>
</div>
<p>Creating the Product class:</p>
<pre class="programlisting">
ClassDef * product = new ClassDef(0, // no base class for Product &quot;Product&quot;); // name of class
</pre>
<p>Adding attributes:</p>
<pre class="programlisting">
product-&gt;addAttribute(Attribute(&quot;Product Number&quot;, Type::intT)); product-&gt;addAttribute(Attribute(&quot;Name&quot;, Type::stringT)); product-&gt;addAttribute(Attribute(&quot;Price&quot;, Type::doubleT)); product-&gt;addAttribute(Attribute(&quot;Weight&quot;, Type::doubleT));
</pre>
<p>Creating the Book class with an attribute list:</p>
<pre class="programlisting">
list&lt;Attribute&gt; attrL; attrL.push_back(Attribute(&quot;Author&quot;, Type::stringT)); attrL.push_back(Attribute(&quot;Title&quot;, Type::stringT)); attrL.push_back(Attribute(&quot;ISBN&quot;, Type::intT)); ClassDef * book = new ClassDef(product, // base class &quot;Book&quot;, attrL.begin(), attrL.end());
</pre>
<p>Creating an object:</p>
<pre class="programlisting">
Object * bscpp(book-newObject());
</pre>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e41" id="d0e41"></a>Setting the
values for the objects:</h2>
</div>
<p>Set an <tt class="literal">int</tt> value by index (don't forget
that index 0 is <tt class="literal">ProductNo</tt>):</p>
<pre class="programlisting">
bscpp-&gt;setValue(0, RealValue&lt;int&gt;(12345));
</pre>
<p>Same for a string value:</p>
<pre class="programlisting">
bscpp-&gt;setValue(4, RealValue&lt;string&gt;(&quot;Bjarne Stroustrup&quot;));
</pre>
<p>Better way: set value by name this gives the most derived
attribute:</p>
<pre class="programlisting">
bscpp-&gt;setValue(&quot;Title&quot;, RealValue&lt;string&gt;(&quot;The C++ Programming Language&quot;)); bscpp-&gt;setValue(&quot;Weight&quot;, Value&lt;double&gt;(370));
</pre></div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e62" id="d0e62"></a>Getting the
values:</h2>
</div>
<p>Display a book:</p>
<pre class="programlisting">
ClassDef::AttrIterator a; size_t idx; for (a = book-&gt;attribBegin(), idx = 0; a != book-&gt;attribEnd(); ++a, ++idx) { cout &lt;&lt; a-&gt;getName() &lt;&lt; &quot;: &quot; &lt;&lt; bscpp-&gt;getValue(idx).asString() &lt;&lt; endl; }
</pre>
<p>and we get:</p>
<pre class="programlisting">
Product Number: 12345 Name: Price: Weight: 370 Author: Bjarne Stroustrup Title: The C++ Programming Language ISBN:
</pre>
<p>So, our MOP is complete. For our sample application, you have to
add a class repository, some nice GUI to define classes and
objects, creating the index for the search machine, provide an
interface for <tt class="literal">ShoppingCart</tt>, but then
you're done, and Susan is happy as she now can create her own new
product categories at runtime.</p>
</div>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e78" id="d0e78"></a>Reflection for
existing C++ classes</h2>
</div>
<p>If you provide the interface for the <tt class=
"literal">ShoppingCart</tt> in our example, you'll find that it
isn't so easy. If all classes are dynamic classes, all access must
go through the MOP: a <tt class="literal">getName()</tt> for
<tt class="literal">Book</tt>:</p>
<pre class="programlisting">
string bookGetName(Object const * book) { if (book-&gt;instanceOf().getName() != &quot;Book&quot;) // throw some exception string name; // name = book-&gt;author + &quot;: &quot; + book-&gt;title; it was so easy... string author = book-&gt;getValue(&quot;Author&quot;).get&lt;string&gt;(); string title = book-&gt;getValue(&quot;Title&quot;).get&lt;string&gt;(); name = author + &quot;: &quot; + title; return name.substr(0, 40); }
</pre>
<p>For a lot of applications, it would be useful to provide some
classes of a hierarchy as C++ classes, e.g. <tt class=
"literal">Product</tt>, but still let the user add classes of the
same hierarchy at runtime, e.g. TShirt. So, let's look at this. If
we want access through our MOP to C++ classes, we need a <tt class=
"literal">getValue()</tt> to which we can give the attribute we
want to access at runtime. So, here it is:</p>
<pre class="programlisting">
Value getValue(Object *o, MemberPointer mp) { return o-&gt;*mp; }
</pre>
<p>The magic lies in <tt class="literal">'-&gt;*</tt>': This is the
pointer-to-member selector of C++.</p>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e109" id="d0e109"></a>Pointer to
members</h2>
</div>
<p><span class="inlinemediaobject"><img src=
"/var/uploads/journals/resources/metaclasses_and_reflection_in_c++_part_2_pointer_to_member.png"
align="right"></span>You can imagine a pointer-to-member in C++ as
an offset<sup>[<a name="d0e117" href="#ftn.d0e117" id=
"d0e117">1</a>]</sup> from the base address of an object to a
specific member. If you apply that offset to such a base address,
you get a reference to the member (Fig. 1). But as a
pointer-to-member is a normal data type in C++, you can store them
in containers, pass them to functions, etc. Thus, you can write the
function above, building the fundamental base for our combination
of C++-classes and runtime-classes.</p>
<p>Let's look at some details of pointer-to-members. As an example,
we use the following class:</p>
<pre class="programlisting">
class Product { // ... protected: RealValue&lt;double&gt; price; }; class Book : public Product { public: // ... private: RealValue&lt;string&gt; author, title; RealValue&lt;double&gt; weight; }; Book b, *bp;
</pre>
<p>A pointer-to-member is a type that is derived from two other
types: The type of the base object (<tt class="literal">Book</tt>
in our example) and the type of the member (<tt class=
"literal">RealValue&lt;&gt;</tt>). The type decorator for a
pointer-to-member is '<tt class="literal">::*</tt>', so let's
define two variables with initialization:</p>
<pre class="programlisting">
RealValue&lt;string&gt; Book::* bookStringMemPtr = &amp;Book::author; RealValue&lt;double&gt; Book::* bookDoubleMemPtr = &amp;Book::weight;
</pre>
<p>The pointer-to-member selector comes in two variations: as
'<tt class="literal">.*</tt>' you can apply it to references of the
class and as <tt class="literal">'-&gt;*</tt>' it takes a pointer.
It is a binary operand, as left operand it takes a reference (or
pointer) to an object and as right operand a pointer-to-member. So,
with the above definitions, you can do things like:</p>
<pre class="programlisting">
b.*bookStringMemPtr = &quot;Bjarne Stroustrup&quot;; // assigns b.author bookStringMemPtr = &amp;Book::title; bp-&gt;*bookStringMemPtr = &quot;The C++ Programming Language&quot;; // assigns b.author
</pre>
<p>Of course, as <tt class="literal">title</tt> is a private member
of <tt class="literal">Book</tt>, the assignment of the
pointer-to-member must be at the scope of that class. But the
pointer-to-member itself can be used even if you don't have access
privileges to the members (as long as you have access to the
pointer-to-member).</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e156" id=
"d0e156"></a>pointer-to-member Types</h2>
</div>
<p>A word about the types: <tt class=
"literal">RealValue&lt;double&gt;Book::*,
RealValue&lt;double&gt;Product::*</tt>, and <tt class=
"literal">BaseValueProduct::*</tt> are different types. But are
there conversions? The C++ standard provides a conversion from a
pointer-to-member of a base class to a pointer-to-member of a
derived class. That makes sense: You can apply an offset to a
member of a base class to the base address of a derived object as
well, as the base is a part of the derived object<sup>[<a name=
"d0e167" href="#ftn.d0e167" id="d0e167">2</a>]</sup>. So you can
assign <tt class="literal">bookDoubleMemPtr =
&amp;Product::price;</tt> as the price is part of each Book
instance. The other way around it obviously doesn't work, you
couldn't initialise <tt class="literal">RealValue&lt;double&gt;
Product::* &amp;Book::author;</tt> as <tt class=
"literal">author</tt> is not a member of each instance of type
<tt class="literal">Product</tt>.</p>
<p>But the standard does not provide a conversion from <tt class=
"literal">RealValue&lt;double&gt;Book::*</tt> to <tt class=
"literal">BaseValueBook::*</tt>, though it would be safe: If the
result type of the pointer-to-member selector is a reference to a
derived class, it can be safely converted to a reference of a
respective base class, so it would also be safe to let the compiler
do the conversion automatically and therefore also convert the
pointer-to-members themselves. As already mentioned, the standard
doesn't provide (implicit) and even doesn't allow (explicit through
static_cast) that conversion, probably because the committee didn't
see any use for pointer-to-data-members at all (see [<a href=
"#Ball-">Ball-</a>]), and for pointer-to-member-functions that
conversion really doesn't make sense.</p>
<p>The problem for us is: we need that conversion. We want to keep
pointer-to-members to all members of a class in one common
container, but what could be the type of that container's elements?
One option would be to force the conversion through a <tt class=
"literal">reinterpret_cast</tt>, but the only thing you can safely
do with a reinterpret_casted thing is to <tt class=
"literal">reinterpret_cast</tt> it back, and for that you have to
store the original type as well. So we use another option: we just
define the conversion! But as C++ doesn't allow you to define your
own conversions to compiler-provided types (and in this sense the
pointer-to-members are compiler defined, though the involved single
types like <tt class="literal">Book</tt> or <tt class=
"literal">BaseValue</tt> are user-defined), we have to define
wrapper classes around them.</p>
<p>Here's the implementation:</p>
<pre class="programlisting">
template &lt;typename BaseType, typename BaseTargetType&gt; class MemPtrBase { public: virtual BaseTargetType &amp; value(BaseType &amp; obj) const = 0; virtual BaseTargetType const &amp; value(BaseType const &amp; obj) const = 0; protected: MemPtrBase() {} virtual ~MemPtrBase() {}; private: MemPtrBase(MemPtrBase const &amp;); MemPtrBase &amp; operator=(MemPtrBase const &amp;); }; template &lt;typename BaseType, typename BaseTargetType, typename TargetType&gt; class TypedMemPtr : public MemPtrBase&lt;BaseType, BaseTargetType&gt; { public: TypedMemPtr(TargetType BaseType::* ptr) : p(ptr) {} BaseTargetType &amp; value(BaseType &amp; obj) const { return obj.*p; } BaseTargetType const &amp; value(BaseType const &amp; obj) const { return obj.*p; } private: TargetType BaseType::* p; }; template &lt;typename BaseType, typename BaseTargetType&gt; class MemPtr { // this is a handle only public: template &lt;typename BaseType2, typename TargetType&gt; explicit MemPtr(TargetType BaseType2::* ptr) : p(new TypedMemPtr&lt;BaseType, BaseTargetType, TargetType&gt;(static_cast&lt;TargetType BaseType::*&gt;(ptr))){} ~MemPtr() { delete p; } BaseTargetType &amp; value(BaseType &amp; obj) const {return p-value(obj); } BaseTargetType const&amp; value(BaseType const&amp; obj)const {return p-&gt;value(obj);} private: MemPtrBase&lt;BaseType, BaseTargetType&gt; * p; };
</pre>
<p>Some notes on the code: <tt class="literal">BaseType</tt> is
used for the class to which a pointer to member is applied (e.g.
<tt class="literal">Book</tt>), <tt class="literal">TargetType</tt>
is the result type to which a pointer-to-member points (<tt class=
"literal">RealValue&lt;double&gt;</tt>), and <tt class=
"literal">BaseTargetType</tt> is the base class of <tt class=
"literal">TargetType (BaseValue). MemPtrBase&lt;&gt;</tt> is the
common base class as we need it (e.g. <tt class=
"literal">MemPtrBase&lt;Book,BaseValue&gt;</tt>, which stands for
<tt class="literal">BaseValueBook::*</tt>), <tt class=
"literal">TypedMemPtr&lt;&gt;</tt> hold an actual C++
pointer-to-member (<tt class=
"literal">TypedMemPtr&lt;Book,RealValue&lt;double&gt; &gt;</tt>),
and <tt class="literal">MemPtr&lt;&gt;</tt> is a handle class
around <tt class="literal">MemPtrBase&lt;&gt;</tt> to store them in
a container. Here, the actual access function is the <tt class=
"literal">value()</tt> member function. If you want, you can add a
global operator '<tt class="literal">-&gt;*</tt>' (as template
function), but you can't provide the operator by a member function
(as the left operand is not the class instance), and you can't
overload '<tt class="literal">.*</tt>' (this is one of the few
non-overloadable operators).</p>
<p>The <tt class="literal">MemPtr</tt> constructor is a member
template with two template parameters: a <tt class=
"literal">BaseType2</tt> and the <tt class=
"literal">TargetType</tt>. The second one is clear as it defines
the actual <tt class="literal">TypedMemPtr</tt> to be constructed,
but the BaseType2 is not so obvious. If we omit the <tt class=
"literal">BaseType2</tt>, so only having:</p>
<pre class="programlisting">
template &lt;typename BaseType, typename BaseTargetType&gt; class MemPtr { // this is a handle only public: template &lt;typename TargetType&gt; explicit MemPtr(TargetType BaseType::* ptr) : p(new TypedMemPtr&lt;BaseType, BaseTargetType, TargetType&gt;(ptr)) {} // ... };
</pre>
<p>and then we try to create a</p>
<pre class="programlisting">
MemPtr&lt;Book, BaseValue&gt; mp2(&amp;Product::price);
</pre>
<p>some compilers give an error, as they cannot fiddle out the
correct conversion. This would be to convert <tt class=
"literal">RealValue&lt;double&gt; Product::*</tt> to <tt class=
"literal">RealValue&lt;double&gt; Book::*</tt>, which should be
done automatically, and then to instantiate <tt class=
"literal">MemPtr</tt>'s constructor with <tt class=
"literal">RealValue&lt;double&gt;</tt> as <tt class=
"literal">TargetType</tt>.</p>
<p>One way to solve this is to explicitly cast the
pointer-to-member:</p>
<pre class="programlisting">
MemPtr&lt;Book, BaseValue&gt; mp2(static_cast&lt;RealValue&lt;double&gt;Book&gt;::*(&amp;Product::price));
</pre>
<p>but that's quite a lot to type. It's actually much easier to
move that explicit conversion into the constructor itself and just
provide an additional template parameter, as shown in the
implementation above. The compiler checks the conversion anyway, so
you will get a compile time error if that conversion is not allowed
(e.g. if you try to convert a <tt class=
"literal">RealValue&lt;double&gt; Book::*</tt> to <tt class=
"literal">RealValue&lt;double&gt; Cd::*</tt>.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e311" id="d0e311"></a>C++
classes</h2>
</div>
<p>The <tt class="literal">MemPtrs</tt> allow you to access the
attribute values of an ordinary C++ object. This helps for one part
of the MOP. But what about the attributes themselves? The compiler
has the necessary knowledge, but unfortunately there is no standard
way to access that knowledge at runtime. So we must provide it and
define an interface for it. To allow a smooth integration with our
existing <tt class="literal">ClassDef</tt>, we provide an
<tt class="literal">Attribute iterator</tt> as interface. For now,
we provide the information about the attributes manually, but in a
following article we'll explore the use of a pre-processor for
that.</p>
<p>So, for our class <tt class="literal">Book</tt> we provide the
following functions:</p>
<pre class="programlisting">
class Book : public Product { typedef MemPtr&lt;Book, FinalValue&gt; MemberPtr; public: // as before static size_t ownAttribCount() {return 5; } static Attribute * ownAttribBegin() { static Attribute a[] = {Attribute(&quot;Author&quot;, Type::stringT), Attribute(&quot;Title&quot;, Type::stringT), Attribute(&quot;Publisher&quot;, Type::stringT), Attribute(&quot;Price&quot;, Type::doubleT), Attribute(&quot;Weight&quot;, Type::doubleT) }; return a; } static Attribute* ownAttribEnd(){return ownAttribBegin() + wnAttribCount(); } static MemberPtr * memberBegin() { static MemberPtr m[] = {MemberPtr(&amp;Book::productNo), MemberPtr(&amp;Product::weight), MemberPtr(&amp;Book::author), MemberPtr(&amp;Book::title), MemberPtr(&amp;Book::publisher), MemberPtr(&amp;Book::price), MemberPtr(&amp;Book::weight) }; return m; } static MemberPtr * memberEnd() { return memberBegin() + 7; } private: RealValue&lt;string&gt; author, title, publisher; RealValue&lt;double&gt; price, weight; };
</pre>
<p>Please note the difference between <tt class=
"literal">ownAttribBegin()</tt> and <tt class=
"literal">memberBegin()</tt>: the first provides information only
about the own attributes, while the latter provides access also to
base class members. This separation makes sense: while on object
level all data members build together one object, on the class
level the base class is a different entity and should be available
as common base class for the meta object protocol as well. But this
separation has consequences: we can't derive a C++ class from a MOP
class (but this is no real restriction) and the C++ base class must
be also made known to the MOP (but that's useful anyway).</p>
<p>We have no function that provides information about the base
classes, as the <tt class="literal">baseClass</tt> in <tt class=
"literal">ClassDef</tt> must be made a <tt class=
"literal">ClassDef</tt> instance as well, as noted above. The C++
base classes are not of much use for our application.</p>
<p>With these functions, we can build a <tt class=
"literal">ClassDef</tt> from a C++ class; it's so easy that we can
even provide a helper function for that:</p>
<pre class="programlisting">
template &lt;typename CppClass&gt; ClassDef makeClass(ClassDef const * base, string const &amp; name) { return ClassDef(base, name, CppClass::ownAttribBegin(), CppClass::ownAttribEnd()); }
</pre>
<p>Now, we can build our <tt class="literal">ClassDef</tt>s for
<tt class="literal">Product</tt> and <tt class="literal">Book</tt>
and create instances from them:</p>
<pre class="programlisting">
ClassDef base(makeClass&lt;DynaProduct&gt;(0, &quot;Product&quot;)); ClassDef book(makeClass&lt;Book&gt;(base, &quot;Book&quot;)); book.newObject();
</pre>
<p>But stop -- though this works, it's not what we want: now, the
instances are not genuine C++ objects, but MOP objects, and all
access must still go through the MOP.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e373" id="d0e373"></a>C++
objects</h2>
</div>
<p>What we want are real C++ objects that we can also access
through the MOP, i.e. through the <tt class="literal">Object</tt>
interface. The OO way to do that is to derive our <tt class=
"literal">Product</tt> from <tt class="literal">Object</tt>, but
though other OO languages like Smalltalk do that, I think there's a
better, less intrusive option: we provide an adaptor.</p>
<p>From [<a href="#Gamma-">Gamma-</a>] we learn that there are two
options for the adaptor pattern: to design the adaptor class as
forwarding wrapper class derived only from <tt class=
"literal">Object</tt> and containing a <tt class=
"literal">Product</tt> member or using multiple inheritance and
derive the adaptor from <tt class="literal">Object</tt> and
<tt class="literal">Product</tt>. For simplicity, we will use the
first option, but real world applications often benefit from the
second approach. So we provide a wrapper class <tt class=
"literal">CppObject</tt> that is derived from <tt class=
"literal">Object</tt> and that holds the original C++ object. It
implements the interface of <tt class="literal">Object</tt>
(<tt class="literal">getValue()</tt> and <tt class=
"literal">setValue()</tt>) through our <tt class=
"literal">MemPtr</tt>s:</p>
<pre class="programlisting">
template &lt;typename OrigClass&gt; class CppObject : public Object{ typedef MemPtr&lt;OrigClass, BaseValue&gt; MemberPtr; public: CppObject(ClassDef const * myClass) : Object(myClass), myObject(), members(OrigClass::memberBegin()) {} virtual Object * clone() const { return new CppObject(*this); } using Object::getValue; // importing getValue(name) using Object::setValue; // importing setValue(name) virtual Value getValue(size_t idx) const { return members[idx].value(myObject); } virtual void setValue(size_t idx, Value const &amp; v) { BaseValue * p = &amp;(members[idx].value(myObject)); p-set(v); } private: MemberPtr * members; OrigClass myObject; };
</pre>
<p><span class="inlinemediaobject"><img src=
"resources/metaclasses_and_reflection_in_c++_part_2_object_hierarchy.png"
align="right"></span>A useful rule of OO design says that only leaf
classes should be concrete, so let's define <tt class=
"literal">Object</tt> as abstract base class and create a new class
<tt class="literal">DynaObject</tt> that resembles our former
<tt class="literal">Object</tt> for real MOP class instances
(Fig.2).</p>
<p>If we now do a <tt class="literal">prod.newObject()</tt>, we
still get it wrong: we now get a <tt class=
"literal">DynaObject</tt>, but we want a <tt class=
"literal">CppObject&lt;Product&gt;</tt>. To solve that, we must
provide the <tt class="literal">ClassDef</tt> with a means to
create the correct kind of object, and the simplest way to do that
is a factory method: we provide a static creation function in
<tt class="literal">CppObject&lt;&gt;</tt> and <tt class=
"literal">DynaObject</tt>, give a pointer to that function to the
<tt class="literal">ClassDef</tt>'s constructor, store it and use
that function in <tt class=
"literal">ClassDef::newObject()</tt>.</p>
<p>Creation functions for <tt class="literal">DynaObject</tt> and
<tt class="literal">CppObject</tt>:</p>
<pre class="programlisting">
Object * DynaObject::newObject(ClassDef const * myClass){ return new DynaObject(myClass); } template &lt;typename OrigClass&gt; Object * CppObject&lt;OrigClass&gt;::newObject(ClassDef const * myClass) { return new CppObject(myClass); }
</pre>
<p>Changes to <tt class="literal">ClassDef</tt>:</p>
<pre class="programlisting">
class ClassDef { public: typedef Object * (*CreateObjFunc)(ClassDef const *); template &lt;typename Iterator&gt; ClassDef(ClassDef const*, string const&amp;, CreateObjFunc objFunc, Iterator, Iterator) : // ... createObj(objFunc) { // ... } ClassDef(ClassDef const *, string &amp; const name_, CreateObjFunc objFunc) : // ... createObj(objFunc) { // ... } Object * newObject() const { definitionFix = true; return (*createObj)(this); } // ... as before private: const CreateObjFunc createObj; // ... as before };
</pre>
<p>And a simple change to <tt class="literal">makeClass</tt>:</p>
<pre class="programlisting">
template &lt;typename CppClass&gt; ClassDef makeClass(ClassDef const * base, string const &amp; name) { return ClassDef(base, name, CppObject&lt;CppClass&gt;::newObject, CppClass::ownAttribBegin(), CppClass::ownAttribEnd()); }
</pre>
<p>Now, everything works. Well -- nearly. If we now try to create a
<tt class="literal">ClassDef</tt> for <tt class=
"literal">Product</tt> with <tt class="literal">makeClass</tt> the
compiler complains about creating an abstract class: <tt class=
"literal">makeClass</tt> gives the <tt class=
"literal">ClassDef</tt> constructor a pointer to <tt class=
"literal">CppObject&lt;Product&gt;::newObject()</tt>, and that
creates a <tt class="literal">Product</tt> instance as part of
<tt class="literal">CppObject&lt;Product&gt;</tt>. This is easily
fixed: just call the <tt class="literal">ClassDef</tt> constructor
directly with a null-pointer for the creation function, thus
prohibiting the creation of a <tt class="literal">Product</tt>
instance through the MOP.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e520" id="d0e520"></a>Usage</h2>
</div>
<p>The MOP, as you have it now, allows you to define the C++
classes as MOP classes as before:</p>
<pre class="programlisting">
ClassDef base(0, &quot;Product&quot;, 0, Product::ownAttribBegin(), Product::ownAttribEnd()); ClassDef book(makeClass&lt;Book&gt;(&amp;base, &quot;Book&quot;));
</pre>
<p>You can create instances of them with</p>
<pre class="programlisting">
book.newObject();
</pre>
<p>You can define new classes derived from <tt class=
"literal">Product</tt></p>
<pre class="programlisting">
ClassDef * tShirt = new ClassDef(&amp;base, &quot;T-Shirt&quot;, DynaObject::newObject); tShirt-&gt;addAttribute(Attribute(&quot;Size&quot;, Type::stringT)); tShirt-&gt;addAttribute(Attribute(&quot;Color&quot;, Type::stringT)); tShirt-&gt;addAttribute(Attribute(&quot;Name&quot;, Type::stringT)); tShirt-&gt;addAttribute(Attribute(&quot;Price&quot;, Type::doubleT)); classReg.registerClass(tShirt);
</pre>
<p>and manipulate instances of existing classes and new classes
through the MOP:</p>
<p>A C++ object:</p>
<pre class="programlisting">
Object * ecpp(book.newObject()); ecpp-&gt;setValue(5, RealValuedouble(22.50)); ecpp-&gt;setValue(0, RealValueint(23456)); ecpp-&gt;setValue(2, RealValuestring(&quot;Scott Meyers&quot;)); ecpp-&gt;setValue(&quot;Title&quot;, RealValuestring(&quot;Effective C++&quot;)); ecpp-&gt;setValue(6, RealValuedouble(280)); size_t idx;cout &lt;&lt; &quot;ecpp:&quot; &lt;&lt; endl; for(a = book.attribBegin(), idx = 0; a != book.attribEnd(); ++a, ++idx) { cout &lt;&lt; a-getName() &lt;&lt; &quot;: &quot; &lt;&lt; ecpp-&gt;getValue(idx).asString() &lt;&lt; endl; } cout &lt;&lt; ecpp-&gt;getValue(&quot;Author&quot;).asString() &lt;&lt; endl;
</pre>
<p>And a dynamic object:</p>
<pre class="programlisting">
Object * ts(tShirt.newObject()); ts-&gt;setValue(0, RealValue&lt;int&gt;(87654)); ts-&gt;setValue(2, RealValue&lt;string&gt;(&quot;XXL&quot;)); ts-&gt;setValue(&quot;Color&quot;, RealValue&lt;string&gt;(&quot;red&quot;)); ts-&gt;setValue(&quot;Price&quot;, RealValue&lt;double&gt;(25.95)); ts-&gt;setValue(&quot;Weight&quot;, RealValue&lt;double&gt;(387)); for(size_t idx = 0; idx != 4; ++idx){ cout &lt;&lt; ts-&gt;getValue(idx).asString() &lt;&lt; endl; }
</pre></div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e547" id="d0e547"></a>C++
Interface</h2>
</div>
<p>You can't access the instances created by the MOP through the
<tt class="literal">Product</tt> interface. For instances of C++
classes you can modify the <tt class="literal">CppObjectT</tt> to
derive from <tt class="literal">T</tt> as we have discussed before,
or better, to provide a member function in <tt class=
"literal">CppObject</tt> that returns a pointer to <tt class=
"literal">myObject</tt>. And for instances of MOP classes you can
define a wrapper around an <tt class="literal">Object</tt> that
implements the <tt class="literal">Product</tt> interface:</p>
<pre class="programlisting">
class DynaProduct : public Product { public: DynaProduct(Object const * o) : obj(o) {} virtual std::string getName() const { Value v = obj-&gt;getValue(&quot;Name&quot;); return v.get&lt;std::string&gt;(); } virtual double getPrice() const { Value v = obj-&gt;getValue(&quot;Price&quot;); return v.get&lt;double&gt;(); } virtual double getWeight() const { Value v = obj-&gt;getValue(&quot;Weight&quot;); return v.get&lt;double&gt;(); } private: Object const * const obj; };
</pre>
<p>And you can't access normal C++ instances of Book through the
MOP; to solve this, you could add another constructor that adopts
the C++ instance by copying (and consequently you should delete the
original one to avoid an object that exists twice) or you could
modify the wrapper to hold only a pointer to the C++ object and add
a member function to return the controlled C++ object on request:
Here, we use the first approach:</p>
<pre class="programlisting">
template &lt;typename OrigClass&gt; CppObject&lt;OrigClass&gt;::CppObject(ClassDef const* myClass, OrigClass const &amp; obj) : Object(myClass), myObject(obj), // calls the copy-ctor of OrigClass, which must be accessible members(OrigClass::memberBegin()) {}
</pre>
<p>And now, you can do this:</p>
<pre class="programlisting">
Book b(&quot;Bjarne Stroustrup&quot;, &quot;The C++ Programming Language&quot;, &quot;Addison-Wesley&quot;, 27.50, 370); CppObject&lt;Book&gt; mb(*book, b); Object * ob = &amp;mb;cout &lt;&lt; &quot;C++ object through MOP&quot; &lt;&lt; endl; for(a = ob-&gt;instanceOf()-&gt;attribBegin(), idx = 0; a != ob-&gt;instanceOf()-&gt;attribEnd(); ++a, ++idx) { cout &lt;&lt; a-&gt;getName() &lt;&lt; &quot;: &quot; &lt;&lt; ob-&gt;getValue(idx).asString() &lt;&lt; endl; }
</pre>
<p>But in general, it's just important that you can define basic
classes in C++ at programming time but allow the user to derive own
classes from these base classes at runtime.</p>
</div>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e585" id=
"d0e585"></a>Applications</h2>
</div>
<p>Is such a MOP approach for C++ actually useful? The pure
reflection mechanism based on pointers-to-members is quite useful
for persistence libraries -- on relational databases or file
formats like XML. This was the application when I first used
pointers-to-members in C++, which were just the C++ replacement of
the old C <tt class="literal">offsetOf</tt> macro that is still in
widespread use for that purpose.</p>
<p>But I also came across quite a lot of applications where a
handful of pre-defined entities provided 98% of the requirements of
the users of the system, but the remaining 2% were so different for
different users that a common solution for all was not adequate.
For these special cases, a full meta-object protocol approach was
really a quite simple and elegant solution that provided all the
flexibility the users requested.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e595" id="d0e595"></a>Two final
remarks</h2>
</div>
<p>Could the same kind of reflection be achieved with get/set
functions instead of pointers-to-members? Perhaps, yes. Some
component mechanisms use that approach (e.g. Borland's VCL). In
that case, a <tt class="literal">get()</tt> and <tt class=
"literal">set()</tt> function for each attribute and a specialized
<tt class="literal">TypedMemPtr&lt;&gt;</tt> for each attribute for
each class is required. That's a lot of work, but with a respective
pre-processor or compiler support that's not a point. But it's
still much more intrusive to add all the getters and setters; and
if they are public, they break encapsulation. Though
pointers-to-members allow direct access to the data, that
encapsulation leak can be much better controlled.</p>
<p>The second remark relates to <tt class=
"literal">RealValue&lt;&gt;</tt>. Are they really necessary for
true reflection purpose? Actually not. In that case, you could
remove <tt class="literal">BaseTargetType</tt> from all <tt class=
"literal">MemPtr</tt> templates, return the <tt class=
"literal">TargetType</tt> in <tt class="literal">TypedMemPtr</tt>'s
getter function, and make the getter function of the <tt class=
"literal">MemPtr</tt> handle a member template function analogous
to the getter function of Value. In the source code for this
article ( <a href="http://www.vollmann.com/download/mop/index.html"
target="_top">http://www.vollmann.com/download/mop/index.html</a>)
you'll find a sample implementation for that.</p>
<p>Though this seems to be a major advantage for pure reflection
applications like persistency libraries, in fact I found it in most
cases quite useful to have a base class like <tt class=
"literal">DbValue</tt> for all persistent attributes to provide
additional functionality like dirty flags, type conversion
specifics, etc.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e637" id="d0e637"></a>Future
articles</h2>
</div>
<p>This article provided reflection and meta-class facilities for
data attributes only. A following article will show the application
of a MOP for the integration of a scripting language. And that will
then allow to extend the MOP with member functions as well.</p>
<p>Another article will look into the capabilities of
pre-processors to provide the reflection information.</p>
<p>And yet another article will look at real applications for
reflection and meta-classes, like DB libraries.</p>
</div>
<div class="bibliography">
<div class="titlepage">
<h2><a name="d0e646" id="d0e646"></a>References</h2>
</div>
<div class="bibliomixed"><a name="Kiczales-" id="Kiczales-"></a>
<p class="bibliomixed">[Kiczales-] Gregor Kiczales, Jim des
Rivi&egrave;res, Daniel G. Bobrow: &quot;The Art of the Metaobject
Protocol&quot;, MIT Press 1991, ISBN 0-262-61074-4</p>
</div>
<div class="bibliomixed"><a name="Coplien" id="Coplien"></a>
<p class="bibliomixed">[Coplien] James O. Coplien: &quot;Advanced C++
Programming Styles And Idioms&quot;, Chapters 8-10, Addison-Wesley,
1992, ISBN 0-201-54855-0</p>
</div>
<div class="bibliomixed"><a name="Buschmann-" id="Buschmann-"></a>
<p class="bibliomixed">[Buschmann-] Frank Buschmann, Regine
Meunier, Hans Rohnert, Peter Sommerlad, Michael Stal:
&quot;Pattern-Oriented Software Architecture: A System of Patterns&quot;,
Wiley 1996, ISBN 0-471-95869-7</p>
</div>
<div class="bibliomixed"><a name="Gamma-" id="Gamma-"></a>
<p class="bibliomixed">[Gamma-] Erich Gamma, Richard Helm, Ralph
Johnson, John Vlissides: &quot;Design Patterns&quot;, Addison-Wesley 1994,
ISBN 0-201-63361-2</p>
</div>
<div class="bibliomixed"><a name="Ball-" id="Ball-"></a>
<p class="bibliomixed">[Ball-] Michael S. Ball, Stephen D. Clamage:
&quot;Pointers-to-Members&quot;, C++ Report 11(10):8-12, Nov/Dec 1999</p>
</div>
</div>
<div class="footnotes"><br>
<hr class="c2" width="100">
<div class="footnote">
<p><sup>[<a name="ftn.d0e117" href="#d0e117" id=
"ftn.d0e117">1</a>]</sup> In fact, a pointer-to-member is not as
easy as an offset. Especially if multiple inheritance comes in,
things become more complicated.</p>
</div>
<div class="footnote">
<p><sup>[<a name="ftn.d0e167" href="#d0e167" id=
"ftn.d0e167">2</a>]</sup> It might be necessary to adjust that
offset, but the compiler cares for that.</p>
</div>
</div>
</p>
<p><strong>Notes:</strong>&nbsp;</p>
<p><em>More fields may be available via dynamicdata ..</em></p>
</div>
</channel>
</rss>
