Design of private map accessor methods

Design of private map accessor methods

Post by Joe Kels » Fri, 25 Jul 2003 09:12:33



I have a class which maintqains a number of private maps, mostly of
type

typedef map<string, string> Cmap;

This class initializes the maps during construction from a text file.
The class user can access maps by passing a key value to retrieve the
map value associated with that key, or by passing the key and new
value to insert or replace a value in the map.  So, each map has two
associated accessory functions.

So, the basic class looks like:

class Cconfig
{
public:
  typedef map<string, string> Cmap;
  typedef pair<int, string> CmodPair;
  typedef map<string, CmodPair> CmodMap;

  Cconfig (string& file) {/* read file */}
  string DbAlias (const string&) const;
  void DbAlias (const string&, const string&);
  // repeated for each map
  CmodPair ModAlias (const string&) const;
  void ModAlias (const string&, const CmodPair&);

private:
  Cmap m_cDbMap;
  // many other maps
  CmodMap m_cModMap;

Quote:};

I also want to provide the user access to the "raw" map.  From a
design standpoint, does simply providing another accessor method to
return a const_reference to the map:

Cmap::const_reference DbMap () const { return m_cDbMap; }

seem better than providing a template function along the lines of:

template <typename T> void
EachDb (T& each)
{
  Cmap::const_iterator b = m_cDbMap.begin ();
  Cmap::const_iterator e = m_cDbMap.end ();
  for_each (b, e, each);

Quote:}

where I replace Db by the private map name.  Can I generalize the
EachDb function to allow easy specialization for each map instance
without duplicating the body?  I don't think I can call for_each
directly on m_cDbMap.begin () and still restrict it to const_iterator.

Basically, I want to try to generalize access to the maps without
exposing them to too much outside manipulation, i.e., only allowing
read-only access outside of the "set" accessor.

      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]

 
 
 

Design of private map accessor methods

Post by Siemel Nara » Fri, 25 Jul 2003 19:23:59


 > I also want to provide the user access to the "raw" map.  From a
 > design standpoint, does simply providing another accessor method to
 > return a const_reference to the map:
 >
 > Cmap::const_reference DbMap () const { return m_cDbMap; }
 >
 > seem better than providing a template function along the lines of:
 >
 > template <typename T> void
 > EachDb (T& each)
 > {
 >   Cmap::const_iterator b = m_cDbMap.begin ();
 >   Cmap::const_iterator e = m_cDbMap.end ();
 >   for_each (b, e, each);
 > }

The second way is nice because you expose nothing about the implementation.

The first way is practical.  One get call size(), begin(), end().  And
they're not limited to just for_each.  They can call transform, copy.  And
they're not forced to write their loops as for_each objects -- sometimes we
still want to write our own loops for ( ; iter!=end; ++iter) { ... }.

BTW, I prefer to write the first one as

     const Cmap& DbMap () const { return m_cDbMap; }

Also consider a third way:  Declare in class Cconfig

     typedef Cmap::const_iterator const_Cmap_iterator;

and functions Cmap_begin() and Cmap_end().

For my class args I do use the for_each idea

template <typename T, int N>
class args
{
    public:
       args(const args<T,N-1>& first, T rest) : d_first(first), d_rest(rest)
{ }

       args<T,N+1> operator+(T rest) const
       {
          return args<T,N+1>(*this,rest);
       }

       template <class U> void for_each(U u) const
       {
          d_first.for_each(u);
          u(d_rest);
       }

       template <class Iter> Iter copy(Iter dest) const
       {
          dest=d_first.copy(dest);
          *dest=d_rest;
          return ++dest;
       }

    private:
       args<T,N-1> d_first;
       T d_rest;

Quote:};

template <typename T>
class args<T,1>
{
    public:
       explicit args(T rest) : d_rest(rest) { }

       args<T,2> operator+(T rest) const
       {
          return args<T,2>(*this,rest);
       }

       template <class U> void for_each(U u) const
       {
          u(d_rest);
       }

       template <class Iter> Iter copy(Iter dest) const
       {
          *dest=d_rest;
          return ++dest;
       }

    private:
       T d_rest;

Quote:};

template <typename T>
class args<T,0>
{
    public:
       args() { }

       args<T,1> operator+(T rest) const
       {
          return args<T,1>(rest);
       }

Quote:};

--
+++++++++++
Siemel Naran

      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]