    <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  :: An Application of Pointers to Members</title>
        <link>https://members.accu.org/index.php/journals/495</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>


        <h2>Journal Articles</h2>


<div class="xar-mod-head"><span class="xar-mod-title">Overload Journal #36 - Mar 2000 + Programming Topics</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/journals/">All</a>

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

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

                     &gt;                         <a href="https://members.accu.org/index.php/journals/c168/">36</a>
                    (7)
<br />

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

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

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

                                            <a href="https://members.accu.org/index.php/journals/c168-65/">Any of these categories</a>

                    -                        <a href="https://members.accu.org/index.php/journals/c168+65/">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;An Application of Pointers to Members</h1>
<p><strong>Author:</strong>&nbsp;</p>
<p>
<strong>Date:</strong> 26 March 2000 17:50:56 +01:00 or Sun, 26 March 2000 17:50:56 +01: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>Most C++ programmers are familiar with the pointer to function
facility provided by the language; the majority of those that do
will be betraying their C heritage. However, few are aware of, or
have used, the pointer to member facility. This article introduces
C++'s pointer to member and then presents a genuine application of
the facility.</p>
<p>The problem with most tutorials on a particular language feature
is that the examples provided are generally not real world ones - a
few demonstration lines of code do not show the programmer how they
should apply the facility, just how to use it. The natural outcome
of this is that the inexperienced programmer will go out of their
way to try to use the facility at the earliest possible
opportunity, when it may not be applicable or serve as the best way
of implementing a certain functionality.</p>
<p>In this description and application I aim to avoid luring the
reader into this pitfall.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e26" id="d0e26"></a>What are
pointers to members?</h2>
</div>
<p>In C and C++ we can declare a pointer to a function as
follows:</p>
<pre class="programlisting">
void exampleFn(char *s, int i) { /* ... */ }
int (*fnptr)(char *, int);
fnptr = &amp;exampleFn;
fnptr(&quot;string&quot;, 1);
</pre>
<p>On the second line we declare a variable that is of type pointer
to function with signature <tt class="literal">(char*, int)</tt>
and return type <tt class="type">void</tt> called <tt class=
"varname">fnptr</tt>. We assign the address of <tt class=
"methodname">exampleFn</tt> to it, and then call <tt class=
"methodname">exampleFn</tt> through it.</p>
<p>When assigning to a function pointer variable the supplied
function must match the signature (return type and parameter types)
exactly.</p>
<p>The use of the <tt class="literal">&amp;</tt> preceding
<tt class="function">exampleFn</tt> is optional in the language, we
could just have legally written <tt class="literal">fnptr =
exampleFn;</tt> Similarly when we call <tt class=
"function">exampleFn</tt> through the <tt class=
"varname">fnptr</tt> variable we are really dereferencing a pointer
to the function so we can write <tt class=
"literal">(*fptr)(&quot;string&quot;, 1);</tt> to call <tt class=
"function">exampleFn</tt> if we choose. However the compiler can
deduce that <tt class="varname">fptr</tt> is a pointer to function
and will dereference appropriately for us. Because of this the
<tt class="literal">*</tt>s are more often than not omitted for
clarity.</p>
<p>Conventionally we may try to tidy up the syntax using <tt class=
"literal">typedef</tt>s:</p>
<pre class="programlisting">
typedef void (*FPTR_T)(char *, int);
FPTR_T fptr = &amp;exampleFn;
fptr(&quot;string&quot;, 1);
</pre>
<p>This declares a new type name called <tt class=
"type">FPTR_T</tt> that points to functions with signature
<tt class="literal">(char *, int)</tt> and return type <tt class=
"type">void</tt>. <tt class="varname">fptr</tt> is a variable of
that type, and the rest follows as before. It is not strictly
necessary, but does makes the syntax a lot more readable.</p>
<p>This much is common to C and C++: C++ provides us a similar
mechanism to point to elements that are within a class. Let's say
that we have something like a function pointer, but that points to
a member function in a class. How would we call it? Being a
function tied to a class we need to provide one extra piece of
information: the object on which the member function is to operate.
If we tried to use the same syntax as above then we would not be
supplying this information.</p>
<p>So how do we do it? Say we have the following class:</p>
<pre class="programlisting">
class ExampleClass
{
  public:
    void exampleMFn(char *s, int i);
    int data; 
// Euch! We all know not to have
// public data members, don't we?
  private:
    void anotherMFn(char *s, int i);
    int moreData;
};
</pre>
<p>Now, to create and use a pointer to the member function
<tt class="methodname">exampleMFn</tt> we write the following:</p>
<pre class="programlisting">
// Create the member pointer
  void (ExampleClass::*mfptr)(char *, int);
  mfptr = &amp;ExampleClass::exampleMFn;
// Use it on an object
  ExampleClass obj;
  (obj.*mfptr)(&quot;string&quot;, 1);
// Use it on an object pointer
  ExampleClass objptr = new ExampleClass;
  (objptr-&gt;*mfptr)(&quot;string&quot;, 1);
  delete objptr;
</pre>
<p>The <tt class="methodname">.*</tt> and <tt class=
"methodname">-&gt;*</tt> operators associate (or bind) the
<tt class="varname">mfptr</tt> member pointer to the object
<tt class="varname">obj</tt> and the object pointed to by
<tt class="varname">objptr</tt> respectively; the member function
call can then proceed as normal. Note that the syntax in both cases
includes an asterisk exactly as did the full version of the
function pointer syntax. However, with pointers to members the
asterisk cannot be omitted. Again, it is common to use <tt class=
"literal">typedef</tt>s to increase readability:</p>
<pre class="programlisting">
typedef void (ExampleClass::*MFPTR_T)(char *, int);
MFPTR_T mfptr = &amp;ExampleClass::exampleMFn;
</pre>
<p>Pointers to members aren't restricted to member functions,
although most tutorials focus entirely on them. We can create a
pointer to a data member too. For example:</p>
<pre class="programlisting">
int ExampleClass::*miptr = &amp;ExampleClass::data;
ExampleClass obj;
obj.*miptr = 10;
</pre>
<p>Pointers to member functions honour run-time polymorphism too.
If a pointer to virtual member function is bound to an object you
are guaranteed that the correct virtual function definition is
called for that object.</p>
<p><tt class="literal">static</tt> member functions are treated
slightly differently since they are not directly associated with an
object. There isn't a pointer to member syntax for them; you use
the normal function pointer syntax. It is an error to try to use
pointer to member syntax in this case.</p>
<p>Pointers to members naturally honour C++'s visibility rules;
otherwise they would be a simple way to get access to a class'
private data! This means that a non-member function of ExampleClass
can only assign pointers to the public parts of the class. For
example:</p>
<pre class="programlisting">
MFPTR_T p1 = &amp;ExampleClass::exampleMFn;  // OK
MFPTR_T p2 = &amp;ExampleClass::anotherMFn;  
// Error: anotherFn is private
</pre>
<p>However a member function can assign a pointer to its class'
non-public members. This is shown in the following (frivolous)
definition of <tt class="methodname">exampleMFn</tt>:</p>
<pre class="programlisting">
void ExampleClass::exampleMFn(char *s, int i)
{
  void (ExampleClass::*fp)(char *, int);
  fp = &amp;anotherMFn; 
// use is OK - note we don't need to fully
// qualify the member function name since
// it is in the class scope
  (this-&gt;*fp)(s, i);
}
</pre>
<p>If a class <tt class="classname">DerivedClass</tt> inherits from
<tt class="classname">ExampleClass</tt> then we can assign the
address of its members to a <tt class="type">MFPT_T</tt> variable.
However, you can only assign members that exist in the <tt class=
"classname">ExampleClass</tt> interface to the variable. This again
preserves C++'s visibility rules.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e172" id="d0e172"></a>When should I
(not) use them?</h2>
</div>
<p>The above do not really show useful examples of how to use
pointers to members, only of how to master the syntax. The next
question we should be asking is why would I want to use a pointer
to member? The following application section is a good example of a
valid use for pointers to members.</p>
<p>Be careful that you're not trying to use a pointer to member
where a better class hierarchy design would allow you to use
virtual functions instead. An indicator of this happening is if the
choice of member is based on some form of class type information.
Virtual functions are preferable in this kind of situation because
the maintenance overhead is smaller (think about what will happen
if you add a new class to the program).</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e179" id="d0e179"></a>An
application of pointers to members</h2>
</div>
<p>I present here a framework for creating easily maintainable
command line utilities in C++. The implementation of the framework
uses pointers to members and should give a good idea of a valid
application of this language mechanism.</p>
<p>Developing command line utilities is a common task (well, for
most UNIX programmers anyway). Such utilities typically have to
parse arguments provided on the command line and act upon them
accordingly. Because this is such an often performed task C and C++
provide us with a mechanism for accessing the command line
arguments in <tt class="function">main</tt> via the <i class=
"parameter"><tt>argc</tt></i> and <i class=
"parameter"><tt>argv</tt></i> parameters.</p>
<p>This framework for parsing the contents of argc and argv follows
the UNIX style of having an arbitrary number of switches, which can
be entered in short or long form. The short form is prefixed by a
single dash, the long form by two dashes. Each switch may be
followed by a number of arguments. An example command line may
be:</p>
<pre class="literallayout">
cmd -s --long1 arg --long2 6 5 --long3
</pre>
<p>Where <tt class="literal">cmd</tt> is the name of the command
line utility, <tt class="literal">-s</tt> is a shortened version of
a switch that takes no arguments, <tt class="literal">--long1</tt>
is a long form switch (note the two dashes) that takes one argument
(here arg), <tt class="literal">--long2</tt> is another long form
that takes two arguments (here 6 and 5), and <tt class=
"literal">--long3</tt> another that takes no arguments.</p>
<p>The following code is a canonical example of the framework. It
implements a command line utility that accepts a number of switches
and requires one unswitched argument that is considered to be an
input filename.</p>
<p>The implementation is split across three files. main.cpp
contains the main function, whilst Application.h and
Application.cpp contain the actual application implementation which
is in a class called (for the sake of argument) <tt class=
"classname">Application</tt>. This code uses the STL.</p>
<p><tt class="filename">Application.h</tt>:</p>
<pre class="programlisting">
#ifndef APPLICATION_H
#define APPLICATION_H
#include &lt;vector&gt;
#include &lt;string&gt;
class Application
{
  public:
    Application(int argc, char *argv[]);
    virtual ~Application();
    int go();
  private:
    static const int  version = 100;       // version no of app (1.00)
    static const char[] name  = &quot;appname&quot;;    // name of app
// Command switch cunningness
    struct Switch {
      typedef void (Application::*handler_t)(int argpos, char *argv[]);
      std::string  lng;  // long switch
      std::string  srt;  // short switch
      int      nargs;     // no. extra arguments following  
      std::string  help;  // help text for switch
      handler_t    handler;   // pointer to handler member
      Switch(std::string l, std::string s, int n, std::string h, handler_t hd)
        : lng(l), srt(s), nargs(n), help(h), handler(hd) {}
    };
// continued on next page
    std::vector &lt;Switch&gt; switches;
// These are the command switch handlers
    void handle_help(int argpos, char *argv[]);
    void handle_version(int argpos, char *argv[]);
    void handle_aardvark(int argpos, char *argv[]);
    std::string filename;
};

#endif
</pre>
<p><tt class="filename">main.cpp</tt>:</p>
<pre class="programlisting">
#include &quot;Application.h&quot;
int main(int argc, char *argv[]) {
  Application app(argc, argv);
  return app.go();
}
</pre>
<p><tt class="filename">Application.cpp</tt>:</p>
<pre class="programlisting">
#include &quot;Application.h&quot;
using std::string;
using std::vector;
Application::Application(int argc, char *argv[]) {
// First, we build a list of the switches understood by this program
  switches.push_back(Switch(&quot;help&quot;, &quot;h&quot;, 0, &quot;provide help&quot;, &amp;handle_help));
  switches.push_back(Switch(&quot;version&quot;, &quot;ver&quot;, 0, &quot;give version no&quot;, &amp;handle_version));
  switches.push_back(Switch(&quot;aardvark&quot;, &quot;a&quot;, 1, &quot;command with one parameter&quot;, &amp;handle_aardvark));
// Now we parse the command line
  if (argc &lt;= 1) {
    handle_version(0, argv);
    handle_help(0, argv);
    exit(0);
  }
  for (int n = 1; n &lt; argc; n++) {
    bool done = false;
    for(vector&lt;Switch&gt;::iterator sw = switches.begin(); !done &amp;&amp; sw != switches.end(); sw++){
      if(argv[n] == string(&quot;-&quot;) + sw-&gt;srt || argv[n] == string(&quot;--&quot;) + sw-&gt;lng){
        done = true;
        if(n + sw-&gt;nargs &gt;= argc) {
          cerr &lt;&lt; &quot;Error in command format (&quot; &lt;&lt; argv[n] 
              &lt;&lt; &quot; expects &quot; &lt;&lt; sw-&gt;nargs &lt;&lt; &quot; arguments)\n&quot;;
          exit(1);
        }
// Call appropriate handler through pointer
        (this-&gt;*(sw-&gt;handler))(n, argv);
        n += sw-&gt;nargs;
      }
    }
// This command line utility needs a filename as an unswitched argument. 
// The following code implements this.
    if (!done) {
       filename = argv[n];
    }
  }
  if (filename == &quot;&quot;) {
    cerr &lt;&lt; &quot;No filename specified.\n&quot;;
    exit(1);
  }
}

Application::~Application() { // Clean up in here ... }
int Application::go() {
// Do something useful ...
  return 0;
}
// This member function displays a nicely formatted help text 
// listing the command line usage of the program.
void Application::handle_help(int, char*[]) {
// You may wish to change the following descriptive text!
  cout &lt;&lt; &quot;Usage: &quot; &lt;&lt; name &lt;&lt; &quot; [OPTION]... [FILE]\n&quot;
      &lt;&lt; &quot;Does this that and the other.\n\n&quot;
      &lt;&lt; &quot;OPTIONs are:\n\n&quot;;
// Work out column widths for the nicely formatted output
  unsigned int srtsize = 0;
  unsigned int lngsize = 0;
  for(vector&lt;Switch&gt;::iterator n = switches.begin(); n != switches.end(); n++) {
    if (n-&gt;srt.size() &gt; srtsize) srtsize = n-&gt;srt.size();
    if (n-&gt;lng.size() &gt; lngsize) lngsize = n-&gt;lng.size();
  }
  srtsize += 2;
  lngsize += 2;
// Produce the nicely formatted output
  for(vector&lt;Switch&gt;::iterator n = switches.begin(); n != switches.end(); n++) {
    cout &lt;&lt; &quot;  -&quot;  &lt;&lt; n-&gt;srt &lt;&lt; string(srtsize-n-&gt;srt.size(), ' ') 
        &lt;&lt; string(&quot; --&quot;) + n-&gt;lng + &quot; &quot; &lt;&lt; string(lngsize-n-&gt;lng.size(), ' ')
       &lt;&lt; n-&gt;help &lt;&lt; endl;
  }
  cout &lt;&lt; &quot;\nSend bug reports to &lt;pete.goodliffe@pacemicro.com&gt;\n&quot;;
  exit(0);
}
void Application::handle_version(int, char*[]) {
  cout &lt;&lt; name &lt;&lt; &quot; version &quot; &lt;&lt; version/100 &lt;&lt; &quot;.&quot; &lt;&lt; version%100
      &lt;&lt; &quot; built on &quot; &lt;&lt; __DATE__ &lt;&lt; &quot;\n&quot;;
}
void Application::handle_aardvark(int argpos, char *argv[]) {
// To get here we are guaranteed that argv contains at least
// this switch in argv[argpos] and the argument in argv[argpos+1]
  string arg = argv[argpos+1];
  cout &lt;&lt; &quot;--aardvark argument is: &quot; &lt;&lt; arg &lt;&lt; endl;
}
</pre>
<p>This code will compile and create a simple command line
'utility', but you may wish to extend it's capabilities slightly
(maybe you won't want the --<tt class="literal">aardvark</tt>
facility!)</p>
<p>As we can see the above Application class uses an internal
vector of <span class="structname">Switch</span>es to store the
table of command line switches it can accept. This table is
populated in the constructor and then used to parse the command
line (passed in <i class="parameter"><tt>argc</tt></i> and
<i class="parameter"><tt>argv</tt></i>). The table of switches is
also used to generate the nicely formatted help text in the
handle_help member function.</p>
<p>We use pointers to members in the <span class=
"structname">Switch</span> structure to store which member function
is used to handle a particular command line switch. This requires
that each handler conform to a particular signature.</p>
<p>Using a framework like this presents us with several benefits.
By not hard-coding the command line argument parsing but using this
more generic table system we can easily add new switches and extend
the functionality of the utility without much extra work. We can
now be assured that the help text will always reflect the command
line interface.</p>
<p>I could have provided the code as a base class to inherit
specific applications from. However, I prefer to leave it as a
framework to build upon due to the kind of customisations it will
need. For example, you may wish to add more unswitched command line
arguments, or change the help text output format. This kind of
change is better suited to modification than inheritance. The
important thing to take away is the table of switches idiom rather
than the code itself.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e266" id=
"d0e266"></a>Conclusion</h2>
</div>
<p>We have seen how to use C++'s pointer to member facility.
Building on this tutorial we have seen an application of the
language feature in real use.</p>
<p>Pointers to members are an extra tool to put into our C++
programming arsenal, to be used as and when appropriate.</p>
</div>
</p>
<p><strong>Notes:</strong>&nbsp;</p>
<p><em>More fields may be available via dynamicdata ..</em></p>
</div>
</channel>
</rss>
