home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #16 / NN_1992_16.iso / spool / comp / lang / cplus / 11745 < prev    next >
Encoding:
Text File  |  1992-07-29  |  14.7 KB  |  788 lines

  1. Newsgroups: comp.lang.c++
  2. Path: sparky!uunet!zaphod.mps.ohio-state.edu!pacific.mps.ohio-state.edu!linac!att!news.cs.indiana.edu!uceng.uc.edu!babbage.ece.uc.edu!ucunix.san.uc.edu!lih
  3. From: lih@ucunix.san.uc.edu (hongbo li)
  4. Subject: c++ template
  5. Message-ID: <1992Jul29.004443.21049@ucunix.san.uc.edu>
  6. Organization: University of Cincinnati
  7. Distribution: usa
  8. Date: Wed, 29 Jul 92 00:44:43 GMT
  9. Lines: 777
  10.  
  11. // Hi, Everybody, I have one problem when I compiled the following  program,
  12. // if someone can help me to fix it, I will very appreciate it.
  13. // The compiler I used is GNU g++  
  14.  
  15. // problem.c
  16. #include<iostream.h>
  17. #include<iomanip.h>
  18. #include<stdio.h>
  19. #include<stream.h>
  20. #include<string.h>
  21. #include<strings.h>
  22. #include<stdarg.h>
  23. #include<errno.h>
  24. #include<libc.h>
  25.  
  26. enum access_mode { f_create, f_update };
  27.  
  28. class recfile{
  29. protected:
  30.  
  31.     FILE* fp;
  32.     char* name;
  33.     int recsize;
  34.     long curr_rec;
  35.     int opened;
  36. public:
  37.     recfile(int recsize=1);
  38.     virtual ~recfile(void) { close() ; cout<<"virtual destructor\n";}
  39.     virtual int open(char* fname, enum access_mode mode);
  40.     virtual int close(void);
  41.     int isopen(void) { return opened; }
  42.     long seek(long recno, int seek_mode=SEEK_SET);
  43.     long rw(int dir, void* data, unsigned nrecs, long recno);
  44.     virtual void err_handler(int errtype, ...);
  45. };
  46.  
  47.  
  48. recfile::recfile(int rs)
  49. {
  50.   name = NULL;
  51.   fp = NULL;
  52.   recsize = rs;
  53.   opened = 0;
  54. }
  55.  
  56. int recfile::open(char* fname, enum access_mode mode)
  57. {
  58. close();
  59.  if ( mode == f_create) 
  60.  {
  61.   fp = fopen(fname, "w+b");
  62.   cout<<"open file successful\n";
  63.   opened=1;
  64. }
  65. else
  66.  {
  67.      fp = fopen(fname, "r");
  68.      if ( fp != NULL )
  69.                        {
  70.                          fclose(fp);
  71.                          fp = fopen(fname, "r+b");
  72.                         }
  73.   }
  74. if ( fp == NULL ) 
  75.      {
  76.        cout<<"enter err2\n";    
  77.        err_handler(2, fname);
  78.           opened = 0;
  79.      }
  80. else {
  81.           name= new char[strlen(fname) + 1 ];
  82.           strcpy( name, fname);
  83.           opened =1 ;
  84.       }
  85. return opened;
  86. }
  87.  
  88.  
  89. int recfile::close(void)
  90. {
  91.  if ( opened ) 
  92.  {
  93.    if ( fclose(fp) == 0 )
  94.    {
  95.      opened = 0;
  96.      delete[] name;
  97.    }
  98.    else  err_handler(3) ; 
  99.  }
  100.  return !opened;
  101. }
  102.  
  103.  
  104. long recfile::seek(long recno, int seek_mode)
  105. {
  106.   long newpos= recno * recsize ;
  107.  if ( opened ) 
  108.   {
  109.  int s;
  110.  
  111.  
  112.   if (  s = fseek(fp, newpos, seek_mode)  )
  113.       {
  114.         err_handler(4, recno ) ;
  115.         return -1;
  116.       }
  117.     
  118.      curr_rec = newpos / recsize;
  119.     return curr_rec ;
  120. }
  121. err_handler(1);
  122.   return -1;
  123. }
  124.  
  125.  
  126.  
  127. long recfile::rw(int dir, void* d, unsigned nr, long recno)
  128. {
  129.   long recsmoved=0;
  130.   if ( opened )
  131.   {
  132.   
  133.      if ( recno == -1 )
  134.      {
  135.           if ( seek (0L, SEEK_CUR) == -1 )    return 0;
  136.      }
  137.      else 
  138.      {
  139.           if ( seek(recno, SEEK_SET) == -1 ) return 0;
  140.      }
  141.  
  142.      if ( dir == 1 )
  143.                     { recsmoved = fwrite(d, recsize, nr, fp );
  144.                       cout<<"successful fwrite"<<recsmoved<<"\n"; 
  145.                     }
  146.      else 
  147.          { recsmoved = fread(d, recsize, nr, fp);
  148.            cout<<"recsmoved = "<<recsmoved<<"\n";
  149.          } 
  150.      if ( recsmoved != nr ) 
  151.                 {
  152.                   cout<<"Enter err 5\n";
  153.                   err_handler(5, dir, recno);
  154.                 } 
  155.     return recsmoved;
  156.    }
  157.    else {
  158.           err_handler(1);
  159.           recsmoved=0;
  160.         } 
  161. return recsmoved;
  162. }
  163.  
  164.  
  165.  
  166. char* dirnames[2] = { "read", "write" };
  167. void recfile::err_handler(int errtype, ... )
  168. {
  169.   va_list arg_ptr;
  170.   int dir;
  171.   long rec;
  172.   char* s;
  173.  
  174.   va_start(arg_ptr, errtype);
  175.   switch ( errtype ) {
  176.    case 0: 
  177.            cout<<"No errori\n"; break;
  178.    case 1:
  179.            cout<<"trying to access unopened file\n";break;
  180.    case 2: 
  181.            cout<<"error 2 "<<"\n"; break;
  182.    case 3: 
  183.            cout<<"error 3 "<<name<<"\n"; break;
  184.    case 4:  
  185.            cout<<"error 4 "<<"\n";break;
  186.    case 5:
  187.            cout<<"error 5 \n"; break;
  188.   }
  189.   va_end(arg_ptr);
  190. }
  191.  
  192.  
  193. class part{
  194.  
  195. protected:
  196.  
  197. int partno;
  198. int qty;
  199. float price;
  200.  
  201. public:
  202.  
  203.   friend ostream& operator<<(ostream& strm, part& p);
  204.   int same_key( part& b);
  205.   void set(int p, int q,  float c){ 
  206.     partno=p, qty=q, price=c;}
  207.  
  208.   void copy(part& p) { set(p.partno, p.qty, p.price);}
  209.   part(void) { set(-1, 0,0); }
  210.   part(part& p) { copy(p); }
  211.   part(int p, int q, float c) { set(p,q,c); }
  212.   void operator=(part &p) { copy(p); }
  213.   int isnull() { return partno == -1; }
  214.   int get_key(void) { return get_partno(); }
  215.   int get_partno(void);
  216.   int get_qty(void);
  217.   int get_price(void);
  218.   void input(void);
  219. };
  220.  
  221.  
  222. void skip_to_eol(istream& s)
  223. {
  224.   char c;
  225.   s.clear();
  226.   while(s.get(c) && c != '\n');
  227. }
  228.  
  229. ostream& operator<<(ostream& strm, part& p)
  230. {
  231.    if ( p.isnull() ) return strm << "Null part";
  232.    strm<<"partno: "<< p.partno<<" ";
  233.    strm<<"qty:    "<< p.qty<<"   ";
  234.    strm<<"price:    "<< p.price;
  235.    return strm;
  236. }
  237.  
  238. int part::same_key( part& b)
  239. {
  240.   return this->partno==b.partno;
  241. }
  242.  
  243. int part::get_partno(void)
  244. {
  245.   cout<<"partno: ";
  246.   if ( cin>>partno ) return 1;
  247.   return 0;
  248.  
  249. int part::get_qty(void)
  250. {
  251.   cout<<"qty: ";
  252.   if ( cin>>qty ) return 1;
  253.   return 0;
  254.  
  255. int part::get_price(void)
  256. {
  257.   cout<<"price: ";
  258.   if ( cin>>price ) return 1;
  259.   return 0;
  260. }
  261. void part::input(void)
  262. {
  263.   while (1)
  264.   {
  265.        if ( get_partno() )
  266.        {
  267.              if ( isnull() ) break;
  268.              if ( get_qty() ) 
  269.              {
  270.                  if ( get_price() ) break;
  271.              }
  272.         }
  273.        cout<<"Invalid input, repress return--- try again:\n";
  274.        skip_to_eol(cin);
  275.    }
  276. }
  277.  
  278.  
  279.  
  280. template<class T>
  281. class file_of: public recfile{
  282. public:
  283.    file_of(void) : (sizeof(T)) {}
  284.  
  285.    long read(T& data, long recno= -1)
  286.    {
  287.        return rw(0, &data, 1, recno);
  288.    }
  289.   
  290.    long write(T& data, long recno= -1)
  291.    {
  292.        return rw(1, &data, 1, recno);
  293.    }
  294. };
  295.  
  296.  
  297. template<class T>
  298. class db:   public file_of<T>
  299. {
  300. protected:
  301.     unsigned nrecs;
  302.     unsigned nitems;
  303.  
  304. public:
  305.     db(void): nrecs(0), nitems(0) {}
  306.     void update_header(void);
  307.     void read_header(void);
  308.     int open(char* fname, enum access_mode mode);
  309.     int close(void);
  310.     unsigned search(T& p);
  311.     unsigned add(T& p);
  312.    unsigned del(T& p, unsigned recno=0);
  313.    unsigned update(T& p, unsigned recno=0);
  314.     void list(ostream& strm);
  315. };
  316.  
  317. template<class T>
  318. void db<T>::read_header(void)
  319. {
  320.    T p;
  321.    cout<<"Enter read_header() \n";
  322.    read( p, 0);
  323.    cout<<" finish read_header()\n"; 
  324.    memcpy(&nrecs, &p, 4);
  325.    memcpy(&nitems,((char*)&p)+4, 4);
  326.    cout<<"nrecs= "<<nrecs<<"nitems= "<<nitems<<"\n";
  327.  
  328. }
  329.  
  330.  
  331. template<class T>
  332. void db<T>::update_header(void)
  333. {
  334.    T p;
  335.           
  336.    memcpy(&p, &nrecs, 4);
  337.    memcpy(((char*)&p)+4, &nitems, 4);
  338.    write(p, 0);
  339. }
  340.  
  341.  
  342. template<class T>
  343. int db<T>::open(char* fname, enum access_mode mode)
  344. {
  345.  
  346.   cout<<"fname= "<<fname<<endl;
  347.   cout<<"mode= "<<mode<<endl;
  348.   recfile::open(fname, mode);
  349.   cout<<" db::open opened= "<<opened<<"\n";
  350.   if ( opened && mode == f_update )
  351.           read_header();
  352.   return opened;
  353. }
  354.  
  355. template<class T>
  356. int db<T>::close(void)
  357. {
  358.    if ( opened ) update_header();
  359.    return recfile::close();
  360. }
  361.  
  362. template<class T>
  363. unsigned db<T>::search(T& p)
  364. {
  365.    unsigned r;
  366.    T q;
  367.    for ( r =1; r<= nrecs; r++ )
  368.    {
  369.         if ( read(q,r) && q.same_key(p) )
  370.         {
  371.               p=q;
  372.               return r;
  373.         }
  374.     }
  375.     return 0;
  376.  }
  377.  
  378. template<class T>
  379. unsigned db<T>::add(T& p)
  380. {
  381.   unsigned r;
  382.   T q;
  383.   r = search(q);
  384.   if ( r ) 
  385.   {
  386.     if ( write(p,r) )
  387.     {
  388.       nitems++;
  389.       update_header();
  390.       return r;
  391.     }
  392.   }
  393.  else
  394.  {
  395.     if ( write(p, nrecs+1) )
  396.     {
  397.       nrecs++; nitems++;
  398.       update_header();
  399.       return nrecs;
  400.     }
  401.   }
  402.   return 0;
  403. }
  404.  
  405.  
  406.  
  407. template<class T>
  408. unsigned db<T>::del(T& p, unsigned recno)
  409. {
  410.   unsigned r;
  411.   if ( recno ) r = recno;
  412.   else r = search(p);
  413.  if ( r )
  414.  {
  415.     T q;
  416.     write(q,r);
  417.     nitems--;
  418.     update_header();
  419.    }
  420.   return r;
  421. }
  422.  
  423. template<class T>
  424. unsigned db<T>::update(T& p, unsigned recno)
  425. {
  426.    unsigned r;
  427.    if ( recno) r = recno;
  428.    else r= search(p);
  429.    if ( r ) 
  430.    {
  431.         write(p, r);
  432.    }
  433.    return r;
  434. }
  435.  
  436.  
  437.  
  438.  
  439. template<class T>
  440. void db<T>::list(ostream& strm)
  441. {
  442.   int cur_rec, recs_seen;
  443.   T p;
  444.   
  445.   for ( cur_rec = 1, recs_seen = 0;
  446.         cur_rec <= nrecs && recs_seen < nitems;
  447.         cur_rec++)
  448.   {
  449.     read(p, cur_rec);
  450.     if ( !p.isnull() )
  451.     {
  452.       strm<<p<<"\n";
  453.       recs_seen++;
  454.     }
  455.    }
  456. }
  457.  
  458.  
  459.  
  460. // test driver
  461. void menu(void)
  462. {
  463.    cout<<"\ndatabase service : \n\n";
  464.    cout<<" c  Create database\n";
  465.    cout<<" o  Open existing database\n";
  466.    cout<<" f  Find part\n";
  467.    cout<<" u  Update part\n";
  468.    cout<<" a  Add part\n";
  469.    cout<<" d  Delete part\n";
  470.    cout<<" l  List parts\n";
  471.    cout<<" q  Quit\n";
  472.    cout<<" h  Help\n\n";
  473. }
  474.  
  475.  
  476. int get_action(void)
  477. {
  478.     char action;
  479.     cout<<" > ";
  480.     cin.clear();
  481.     cin>>action;
  482.     cout<<" action: "<<action<<"\n";
  483.     return action;
  484. }
  485.  
  486. int do_action(db<part>& f, int act)
  487. {
  488.    part p;
  489.    char c, fname[80];
  490.    unsigned rec;
  491.  
  492.    if ( act != 'q' && act != 'c' && act != 'o' &&
  493.         act != 'h' && !f.isopen() )
  494.    {
  495.       cout<< "Database not opened\n";
  496.       return act;
  497.    }
  498.    
  499.   switch(act){
  500.     case 'q':  cout<<"Closing down database ...\n";
  501.                f.close();
  502.                break;
  503.     case 'c':  cout<<"Enter file name: ";
  504.                cin.get(c);
  505.                cin.get(fname, 80);
  506.                cout<<" c : fname= "<<fname<<endl; 
  507.                f.open(fname, f_create);
  508.                break; 
  509.  
  510.     case 'o':  cout<<"Enter file name: ";
  511.                cin.get(c);
  512.                cin.get(fname, 80);
  513.                f.open(fname, f_update);
  514.                break; 
  515.     case 'f':  cout<<"find ";
  516.                if ( p.get_key())
  517.                {
  518.                    if ( ( rec = f.search(p) ) !=0 )
  519.                    {
  520.                        cout<<"Part found at rec "<<rec<<"\n";
  521.                        cout<<p<<"\n";
  522.                     }
  523.                     else   cout<<"Part not found\n";
  524.                 }
  525.                 break;
  526.  
  527.      case 'u': cout<<"Update ";
  528.                if ( p.get_key() )
  529.                {
  530.                    if ( ( rec=f.search(p) ) != 0 )
  531.                    {
  532.                          cout<<p<<"\n";
  533.                          cout<<"Enetr new part info: \n";
  534.                          p.input();
  535.                          if ( !p.isnull() )
  536.                          {
  537.                             if ( f.update(p, rec) )
  538.                                    cout<<"Part successfully update\n";
  539.                             else   cout<<"Error updating part\n";
  540.                          }
  541.                          else cout<<"Part not changed\n";
  542.                       
  543.                    }
  544.                    else cout<<"Part not found\n";
  545.                }
  546.                break;
  547.  
  548. case 'd':  cout<<"Delete ";
  549.            if ( p.get_key() )
  550.            {
  551.              if( ( rec=f.search(p) ) !=0)
  552.              {
  553.                 cout<<p<<"\n";
  554.                 cout<<"Do you still wish to delete? ";
  555.                 cin>>c;
  556.                 if ( c=='y' || c=='Y' ) 
  557.                 {
  558.                   if ( f.del(p, rec) )
  559.                      cout<<"Part deleted\n";
  560.                   else  cout<<"Error deleting part\n";
  561.                  }
  562.                          
  563.                 else cout<<"Part not deleted\n";
  564.               }
  565.               else cout<<"Part not found\n";
  566.             }
  567.            break;
  568.  
  569. case 'a':  cout<<"Enter part to add below: \n";
  570.            p.input();
  571.            if ( !p.isnull() ) 
  572.            {
  573.              if ( ( rec=f.add(p) ) != 0 ) 
  574.              {
  575.                  cout<<"Part stored at rec "<<rec<<"\n";
  576.                  cout<<p<<"\n";
  577.              }
  578.            }
  579.            break;
  580.  
  581. case 'l':  f.list(cout);
  582.                  break;
  583.      
  584.      case 'h':  menu();
  585.                  break;
  586.      }
  587.     return act;
  588. }
  589.  
  590. int main()
  591. {
  592.    db<part> f;
  593.    int i;
  594.    menu();
  595.      while(1)
  596.     {
  597.         i=get_action();
  598.         if ( i =='q') break;
  599.         do_action(f, i);
  600.      };
  601. }
  602.  
  603. % g++ problem.c -o problem
  604. problem.c:309: template for method `update' doesn't match any in class `db<part>'
  605. problem.c:309: template for method `del' doesn't match any in class `db<part>'
  606.  
  607.  
  608.  
  609.  
  610. But, if I change  it into the following  :
  611.      .
  612.      .
  613.      . ( all the parts of the program is kept the same except :  )
  614. class db:   public file_of<part>
  615. {
  616. protected:
  617.     unsigned nrecs;
  618.     unsigned nitems;
  619.  
  620. public:
  621.     db(void): nrecs(0), nitems(0) {}
  622.     void update_header(void);
  623.     void read_header(void);
  624.     int open(char* fname, enum access_mode mode);
  625.     int close(void);
  626.     unsigned search(part& p);
  627.     unsigned add(part& p);
  628.    unsigned del(part& p, unsigned recno=0);
  629.    unsigned update(part& p, unsigned recno=0);
  630.     void list(ostream& strm);
  631. };
  632.  
  633. void db::read_header(void)
  634. {
  635.    part p;
  636.    cout<<"Enter read_header() \n";
  637.    read( p, 0);
  638.    cout<<" finish read_header()\n"; 
  639.    memcpy(&nrecs, &p, 4);
  640.    memcpy(&nitems,((char*)&p)+4, 4);
  641.    cout<<"nrecs= "<<nrecs<<"nitems= "<<nitems<<"\n";
  642.  
  643. }
  644.  
  645.  
  646. void db::update_header(void)
  647. {
  648.    part p;
  649.           
  650.    memcpy(&p, &nrecs, 4);
  651.    memcpy(((char*)&p)+4, &nitems, 4);
  652.    write(p, 0);
  653. }
  654.  
  655.  
  656. int db::open(char* fname, enum access_mode mode)
  657. {
  658.  
  659.   cout<<"fname= "<<fname<<endl;
  660.   cout<<"mode= "<<mode<<endl;
  661.   recfile::open(fname, mode);
  662.   cout<<" db::open opened= "<<opened<<"\n";
  663.   if ( opened && mode == f_update )
  664.           read_header();
  665.   return opened;
  666. }
  667.  
  668. int db::close(void)
  669. {
  670.    if ( opened ) update_header();
  671.    return recfile::close();
  672. }
  673.  
  674. unsigned db::search(part& p)
  675. {
  676.    unsigned r;
  677.    part q;
  678.    for ( r =1; r<= nrecs; r++ )
  679.    {
  680.         if ( read(q,r) && q.same_key(p) )
  681.         {
  682.               p=q;
  683.               return r;
  684.         }
  685.     }
  686.     return 0;
  687.  }
  688.  
  689. unsigned db::add(part& p)
  690. {
  691.   unsigned r;
  692.   part q;
  693.   r = search(q);
  694.   if ( r ) 
  695.   {
  696.     if ( write(p,r) )
  697.     {
  698.       nitems++;
  699.       update_header();
  700.       return r;
  701.     }
  702.   }
  703.  else
  704.  {
  705.     if ( write(p, nrecs+1) )
  706.     {
  707.       nrecs++; nitems++;
  708.       update_header();
  709.       return nrecs;
  710.     }
  711.   }
  712.   return 0;
  713. }
  714.  
  715. unsigned db::del(part& p, unsigned recno)
  716. {
  717.   unsigned r;
  718.   if ( recno ) r = recno;
  719.   else r = search(p);
  720.  if ( r )
  721.  {
  722.     part q;
  723.     write(q,r);
  724.     nitems--;
  725.     update_header();
  726.    }
  727.   return r;
  728. }
  729.  
  730. unsigned db::update(part& p, unsigned recno)
  731. {
  732.    unsigned r;
  733.    if ( recno) r = recno;
  734.    else r= search(p);
  735.    if ( r ) 
  736.    {
  737.         write(p, r);
  738.    }
  739.    return r;
  740. }
  741.  
  742. void db::list(ostream& strm)
  743. {
  744.   int cur_rec, recs_seen;
  745.   part p;
  746.   
  747.   for ( cur_rec = 1, recs_seen = 0;
  748.         cur_rec <= nrecs && recs_seen < nitems;
  749.         cur_rec++)
  750.   {
  751.     read(p, cur_rec);
  752.     if ( !p.isnull() )
  753.     {
  754.       strm<<p<<"\n";
  755.       recs_seen++;
  756.     }
  757.    }
  758. }
  759.  
  760. .
  761. .
  762. .
  763.  
  764. int main( ){
  765.     db f;
  766.     .
  767.     .
  768.     . 
  769. }
  770.  
  771. then the program is ok, no compiling errors. I can run it. 
  772. what's the problem? maybe I can not do this? : 
  773.  
  774. template<class T>
  775. class file_of: public recfile{
  776.     .......... }
  777.  
  778. template<class T>
  779. class db:   public file_of<T>
  780. {    ........... }
  781.  
  782.  
  783. if someone  can give me the answer , I appreciate it vry much.
  784. Thanx lot for help in advance.
  785. my E_Mail :  lih@ucunix.san.uc.edu   
  786.