    <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  :: Controlling access to objects by using private
interfaces</title>
        <link>https://members.accu.org/index.php/journals/580</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 #28 - Oct 1998 + 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/c175/">28</a>
                    (10)
<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/c175-65/">Any of these categories</a>

                    -                        <a href="https://members.accu.org/index.php/journals/c175+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;Controlling access to objects by using private
interfaces</h1>
<p><strong>Author:</strong>&nbsp;</p>
<p>
<strong>Date:</strong> 27 October 1999 18:23:02 +01:00 or Wed, 27 October 1999 18:23:02 +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>I read Overload 27 on the train this morning and Francis'
article &quot;Exploring Patterns Part 2&quot; made me think.</p>
<p>In that article Francis develops some host classes containing
data and he wants to limit access to that data to a particular
hierarchy of classes (the base of the hierarchy being MyVisitor).
The solution he provides in the postscript section makes the host
data private and makes MyVisitor a friend of the host classes.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e24" id="d0e24"></a>But what is
friendship?</h2>
</div>
<p>One of the ideas of OO programming is that an object presents an
interface that clients can use to access it. In fact an object can
provide several interfaces. An interface is basically a collection
of operations you can call and attributes you can access.</p>
<p>C++ objects provide three standard interfaces to an object: the
public interface, intended for use by everyone, the protected
interface, intended for use by derived classes, and the private
interface, intended for use by only that class.</p>
<p>Friendship is about allowing a privileged class to access a
special interface. However, the C++ friendship facility is limited
(by that definition) because the only interface it can provide
access to is the private one (which I mean to include everything
that's declared as public and protected too).</p>
<p>Many problems, including Francis's, require one object to get
access to a special interface of another object. We usually solve
that problem by using friendship but if we could explicitly define
special interfaces and make each available only to certain classes,
we'd have a very powerful and flexible alternative. The advantages
would be that we could provide exactly the interface that we wanted
(rather than the entire private interface) and we could provide
different interfaces to different clients.</p>
<p>One way to provide additional interfaces is to inherit from base
classes. If we have a Square class that inherits from a Shape class
then, as an external client, we have two interfaces through which
we can access a Square object: as a Shape or as a Square. However,
these interfaces don't have any restrictions on who can use
them&hellip; unless we use private inheritance.</p>
<p>To provide special interfaces and restrict access to them, we
can declare the interfaces as abstract base classes, inherit them
privately and then write access functions that provide (restricted)
access to the interface.</p>
<p>Here's some example code that defines a class, Host, with three
different interfaces. There are three (abstract) visitor classes
that are allowed to access the Host's interfaces but notice that
each visitor is restricted to accessing the Host through a
particular interface of the Host. Finally, to make the code
actually do something, there are three concrete visitors (each
implementing one of the abstract visitors) and a main function that
makes a host and uses the visitors.</p>
<p>Notice that Host gives access to its interfaces using the
access&hellip; methods. The parameter type of the method restricts
access to the interface. For example, accessI2() accepts only an
I2Visitor as a parameter and so only I2Visitors (including classes
derived from I2Visitor) can access Host's Interface2.</p>
<p>The UML class diagram below gives an overview of all these
classes and their relationships. Remember this example is
intentionally complicated; it's intended to show several interfaces
and several types of visitor. Usually, you won't need such
complication.</p>
<div class="c2"><img src=
"/var/uploads/journals/resources/Field%20uml%20diagram%20private%20interfaces.png" align=
"middle"></div>
<pre class="programlisting">
class GetInterface
{ public:
    virtual int getA() const = 0;
    virtual int getB() const = 0;
};
</pre>
<p>An example of an interface that extends another interface.</p>
<pre class="programlisting">
class GetSetInterface : public GetInterface
{ public:
    virtual void setA(int a) = 0;
    virtual void setB(int b) = 0;
};
</pre>
<p>An example of an interface with an attribute.</p>
<pre class="programlisting">
class Interface2
{ public:
    int c;
};
</pre>
<p>Here are the classes that are allowed to access the Host. Three
different 'visitors' which use the different interfaces provided by
Host.</p>
<pre class="programlisting">
class ConstABVisitor
{ public:
    virtual void visitHost(const GetInterface&amp; i) = 0;
};

class ABVisitor
{ public:
    virtual void visitHost(GetSetInterface&amp; i) = 0;
};

class I2Visitor
{ public:
    virtual void visitHost(Interface2&amp; i) = 0;
};
</pre>
<p>Define the class with multiple (private) interfaces.</p>
<pre class="programlisting">
class Host : private GetSetInterface, private Interface2
{ private:
    int a;
    int b;

    /* Implementation of interfaces - declared private */
    int getA() const { return a; }
    int getB() const { return b; }
    void setA(int new_a) { a = new_a; }
    void setB(int new_b) { b = new_b; }

  public:
    /* Provide public functions to allow (restricted) access to interfaces */
    void accessConstAB(ConstABVisitor&amp; v) const { v.visitHost(*this); }
    void accessAB(ABVisitor&amp; v) { v.visitHost(*this); }
    void accessI2(I2Visitor&amp; v) { v.visitHost(*this); }
};
</pre>
<p>Example concrete visitors.</p>
<pre class="programlisting">
class ConcreteConstABVisitor : public ConstABVisitor
{ public:
    void visitHost(const GetInterface&amp; i) { cout &lt;&lt; i.getA() &lt;&lt; i.getB(); }
};

class ConcreteABVisitor : public ABVisitor
{ public:
    void visitHost(GetSetInterface&amp; i) { i.setA(1); i.setB(2); }
};

class ConcreteI2Visitor : public I2Visitor
{ public:
    void visitHost(Interface2&amp; i) { i.c = 3; }
};
</pre>
<p>Example usage of the pattern.</p>
<pre class="programlisting">
int main(void)
{ 
  Host host;
  ConcreteConstABVisitor cab;
  ConcreteABVisitor ab;
  ConcreteI2Visitor i2;
  
  host.accessAB(ab);
  host.accessConstAB(cab);
  host.accessI2(i2);

  return 0;
};
</pre></div>
</p>
<p><strong>Notes:</strong>&nbsp;</p>
<p><em>More fields may be available via dynamicdata ..</em></p>
</div>
</channel>
</rss>
