home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #20 / NN_1992_20.iso / spool / comp / lang / cplus / 13683 < prev    next >
Encoding:
Text File  |  1992-09-15  |  4.0 KB  |  191 lines

  1. Newsgroups: comp.lang.c++
  2. Path: sparky!uunet!mcsun!Germany.EU.net!Urmel.Informatik.RWTH-Aachen.DE!messua!schreib
  3. From: schreib@messua.informatik.rwth-aachen.de (Dirk Schreib)
  4. Subject: Different reader/writer functions for arrays???
  5. Message-ID: <schreib.716568141@messua>
  6. Sender: news@Urmel.Informatik.RWTH-Aachen.DE (Newsfiles Owner)
  7. Nntp-Posting-Host: messua
  8. Organization: Rechnerbetrieb Informatik  /  RWTH Aachen
  9. Date: 15 Sep 92 14:42:21 GMT
  10. Lines: 179
  11.  
  12.  
  13. Question:
  14.  
  15.    I'd like to create a generic, dynamic array, which has different
  16.    operations for reading and writing.
  17.  
  18.    The purpose is to handle accesses to elements that are out of the
  19.    array's bounds. In case of a write access, the array should resize
  20.    itself, in case of a read access, it should return a default
  21.    object.
  22.  
  23.  
  24. First thought: trivial!
  25.  
  26.   Make a template class (name: "Grid"), overload operator() 
  27.   (I want a multidimensional array)
  28.   and return a description object. (name: "D")
  29.  
  30.   For this description class, overload operator =() for assignment and
  31.   operator T () for reading. (array has type T)
  32.  
  33.  
  34. This works... but:
  35.  
  36.  
  37.   Maybe T is a "pointer to class".
  38.  
  39.   You cannot write grid(x,y)->f() because grid(x,y) is of type D.
  40.  
  41.  
  42. Second thought: A little bit complex!
  43.  
  44.   I've overloaded operator ->() for class D. Also
  45.   operator &().
  46.  
  47. This works...but:
  48.  
  49.   You have to overload nearly all operators which will be needed.
  50.  
  51.  
  52. But there are still problems:
  53.  
  54.   There might be functions like:
  55.  
  56.   void foo(T & arrayobject);
  57.  
  58.   Is this a write or read access?
  59.  
  60.   or
  61.  
  62.   operator >> (ifpstream &, T &);
  63.  
  64.   This is a write access!! But how to handle?
  65.  
  66.   or
  67.  
  68.   delete grid(x,y) will not work, but delete (T *) grid(x,y) will.
  69.  
  70.  
  71. Last thought: Too complex!!
  72.  
  73.  
  74. Have I missed the point? Is there any feature in C++ which
  75. permits this?
  76.  
  77. Any help would be appreciated.
  78.  
  79.  
  80. Dirk
  81.  
  82.  
  83. P.S.: I've included my template-version.
  84.  
  85. ---------------------------------------------------
  86. #include <iostream.h>
  87. #include <assert.h>
  88.  
  89. template <class T>
  90. class Grid
  91.     {
  92. protected:
  93.     int xs,ys;
  94.     int dx, dy;
  95.     T * mem;
  96.     T Empty;
  97. public:
  98.     void grow(int nxs, int nys);
  99.     int XSize() const { return xs;};
  100.     int YSize() const { return ys;};
  101.  
  102.     class D;
  103.  
  104.     friend D;
  105.  
  106.     class D
  107.         {
  108.         Grid & g;
  109.         int x,y;
  110.     public:
  111.         D(Grid & ng, int nx, int ny): g(ng), x(nx), y(ny) {};
  112.  
  113.         T operator ->()
  114.             {
  115.             if ( (x >= g.xs ) || ( y >= g.ys))
  116.                 {
  117.                 return g.Empty;
  118.                 }
  119.             else
  120.                 return g.mem[x*g.ys+y];
  121.             };
  122.  
  123.         T * operator & ()
  124.             {
  125.             if ( (x >= g.xs ) || ( y >= g.ys))
  126.                 return &g.Empty;
  127.             else
  128.                 return &g.mem[x*g.ys+y];
  129.             };
  130.  
  131.         operator T ()
  132.             {
  133.             if ( (x >= g.xs ) || ( y >= g.ys))
  134.                 return g.Empty;
  135.             else
  136.                 return g.mem[x*g.ys+y];
  137.             };
  138.  
  139.         T operator = (const T& t)
  140.             {
  141.             if ( (x >= g.xs ) || ( y >= g.ys))
  142.                 g.grow(x+1,y+1);
  143.             return g.mem[x*g.ys+y] = t;
  144.             };
  145.         };
  146.  
  147.  
  148.     Grid(T aEmpty,int nxs = 1, int nys = 1, int ndx = 0, int ndy = 0):
  149.       xs(nxs), ys(nys), dx(ndx), dy(ndy), Empty(aEmpty)
  150.         {
  151.         mem = new T[xs*ys];
  152.         memset(mem, 0, xs * ys * sizeof(T));
  153.         };
  154.  
  155.     ~Grid()
  156.         {
  157.         delete [] mem;
  158.         };
  159.  
  160.     D operator() (int x, int y)
  161.         {
  162.         assert( (x>=0) && (y>=0) );
  163.         return D(*this, x,y);
  164.         };
  165.     };
  166.  
  167. template <class T>
  168. void Grid<T>::grow(int nxs, int nys)
  169.     {
  170.     if (nxs < xs) nxs = xs;
  171.     if (nys < ys) nys = ys;
  172.     nxs += dx; nys +=dy;
  173.     T * help = new T[nxs*nys];
  174.     memset(help, 0, nxs * nys * sizeof(T));
  175.     for (int x=0; x <xs; x++)
  176.         for(int y=0; y <ys; y++)
  177.             help[x*nys+y] = mem[x*ys+y];
  178.     xs = nxs; ys = nys;
  179.     delete [] mem;
  180.     mem = help;
  181.     };
  182.  
  183.  
  184. #endif
  185.  
  186. -- 
  187. Dirk Schreib, Markt 54, 5100 Aachen,  Germany
  188. Tel.: +49 241 30896,       FAX: +49 241 24359
  189. CompuServe: 100021,2576
  190. Email: schreib@POOL.Informatik.RWTH-Aachen.DE
  191.