home *** CD-ROM | disk | FTP | other *** search
- Newsgroups: comp.lang.c++
- 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
- From: lih@ucunix.san.uc.edu (hongbo li)
- Subject: c++ template
- Message-ID: <1992Jul29.004443.21049@ucunix.san.uc.edu>
- Organization: University of Cincinnati
- Distribution: usa
- Date: Wed, 29 Jul 92 00:44:43 GMT
- Lines: 777
-
- // Hi, Everybody, I have one problem when I compiled the following program,
- // if someone can help me to fix it, I will very appreciate it.
- // The compiler I used is GNU g++
-
- // problem.c
- #include<iostream.h>
- #include<iomanip.h>
- #include<stdio.h>
- #include<stream.h>
- #include<string.h>
- #include<strings.h>
- #include<stdarg.h>
- #include<errno.h>
- #include<libc.h>
-
- enum access_mode { f_create, f_update };
-
- class recfile{
- protected:
-
- FILE* fp;
- char* name;
- int recsize;
- long curr_rec;
- int opened;
- public:
- recfile(int recsize=1);
- virtual ~recfile(void) { close() ; cout<<"virtual destructor\n";}
- virtual int open(char* fname, enum access_mode mode);
- virtual int close(void);
- int isopen(void) { return opened; }
- long seek(long recno, int seek_mode=SEEK_SET);
- long rw(int dir, void* data, unsigned nrecs, long recno);
- virtual void err_handler(int errtype, ...);
- };
-
-
- recfile::recfile(int rs)
- {
- name = NULL;
- fp = NULL;
- recsize = rs;
- opened = 0;
- }
-
- int recfile::open(char* fname, enum access_mode mode)
- {
- close();
- if ( mode == f_create)
- {
- fp = fopen(fname, "w+b");
- cout<<"open file successful\n";
- opened=1;
- }
- else
- {
- fp = fopen(fname, "r");
- if ( fp != NULL )
- {
- fclose(fp);
- fp = fopen(fname, "r+b");
- }
- }
- if ( fp == NULL )
- {
- cout<<"enter err2\n";
- err_handler(2, fname);
- opened = 0;
- }
- else {
- name= new char[strlen(fname) + 1 ];
- strcpy( name, fname);
- opened =1 ;
- }
- return opened;
- }
-
-
- int recfile::close(void)
- {
- if ( opened )
- {
- if ( fclose(fp) == 0 )
- {
- opened = 0;
- delete[] name;
- }
- else err_handler(3) ;
- }
- return !opened;
- }
-
-
- long recfile::seek(long recno, int seek_mode)
- {
- long newpos= recno * recsize ;
- if ( opened )
- {
- int s;
-
-
- if ( s = fseek(fp, newpos, seek_mode) )
- {
- err_handler(4, recno ) ;
- return -1;
- }
-
- curr_rec = newpos / recsize;
- return curr_rec ;
- }
- err_handler(1);
- return -1;
- }
-
-
-
- long recfile::rw(int dir, void* d, unsigned nr, long recno)
- {
- long recsmoved=0;
- if ( opened )
- {
-
- if ( recno == -1 )
- {
- if ( seek (0L, SEEK_CUR) == -1 ) return 0;
- }
- else
- {
- if ( seek(recno, SEEK_SET) == -1 ) return 0;
- }
-
- if ( dir == 1 )
- { recsmoved = fwrite(d, recsize, nr, fp );
- cout<<"successful fwrite"<<recsmoved<<"\n";
- }
- else
- { recsmoved = fread(d, recsize, nr, fp);
- cout<<"recsmoved = "<<recsmoved<<"\n";
- }
- if ( recsmoved != nr )
- {
- cout<<"Enter err 5\n";
- err_handler(5, dir, recno);
- }
- return recsmoved;
- }
- else {
- err_handler(1);
- recsmoved=0;
- }
- return recsmoved;
- }
-
-
-
- char* dirnames[2] = { "read", "write" };
- void recfile::err_handler(int errtype, ... )
- {
- va_list arg_ptr;
- int dir;
- long rec;
- char* s;
-
- va_start(arg_ptr, errtype);
- switch ( errtype ) {
- case 0:
- cout<<"No errori\n"; break;
- case 1:
- cout<<"trying to access unopened file\n";break;
- case 2:
- cout<<"error 2 "<<"\n"; break;
- case 3:
- cout<<"error 3 "<<name<<"\n"; break;
- case 4:
- cout<<"error 4 "<<"\n";break;
- case 5:
- cout<<"error 5 \n"; break;
- }
- va_end(arg_ptr);
- }
-
-
- class part{
-
- protected:
-
- int partno;
- int qty;
- float price;
-
- public:
-
- friend ostream& operator<<(ostream& strm, part& p);
- int same_key( part& b);
- void set(int p, int q, float c){
- partno=p, qty=q, price=c;}
-
- void copy(part& p) { set(p.partno, p.qty, p.price);}
- part(void) { set(-1, 0,0); }
- part(part& p) { copy(p); }
- part(int p, int q, float c) { set(p,q,c); }
- void operator=(part &p) { copy(p); }
- int isnull() { return partno == -1; }
- int get_key(void) { return get_partno(); }
- int get_partno(void);
- int get_qty(void);
- int get_price(void);
- void input(void);
- };
-
-
- void skip_to_eol(istream& s)
- {
- char c;
- s.clear();
- while(s.get(c) && c != '\n');
- }
-
- ostream& operator<<(ostream& strm, part& p)
- {
- if ( p.isnull() ) return strm << "Null part";
- strm<<"partno: "<< p.partno<<" ";
- strm<<"qty: "<< p.qty<<" ";
- strm<<"price: "<< p.price;
- return strm;
- }
-
- int part::same_key( part& b)
- {
- return this->partno==b.partno;
- }
-
- int part::get_partno(void)
- {
- cout<<"partno: ";
- if ( cin>>partno ) return 1;
- return 0;
- }
-
- int part::get_qty(void)
- {
- cout<<"qty: ";
- if ( cin>>qty ) return 1;
- return 0;
- }
-
- int part::get_price(void)
- {
- cout<<"price: ";
- if ( cin>>price ) return 1;
- return 0;
- }
- void part::input(void)
- {
- while (1)
- {
- if ( get_partno() )
- {
- if ( isnull() ) break;
- if ( get_qty() )
- {
- if ( get_price() ) break;
- }
- }
- cout<<"Invalid input, repress return--- try again:\n";
- skip_to_eol(cin);
- }
- }
-
-
-
- template<class T>
- class file_of: public recfile{
- public:
- file_of(void) : (sizeof(T)) {}
-
- long read(T& data, long recno= -1)
- {
- return rw(0, &data, 1, recno);
- }
-
- long write(T& data, long recno= -1)
- {
- return rw(1, &data, 1, recno);
- }
- };
-
-
- template<class T>
- class db: public file_of<T>
- {
- protected:
- unsigned nrecs;
- unsigned nitems;
-
- public:
- db(void): nrecs(0), nitems(0) {}
- void update_header(void);
- void read_header(void);
- int open(char* fname, enum access_mode mode);
- int close(void);
- unsigned search(T& p);
- unsigned add(T& p);
- unsigned del(T& p, unsigned recno=0);
- unsigned update(T& p, unsigned recno=0);
- void list(ostream& strm);
- };
-
- template<class T>
- void db<T>::read_header(void)
- {
- T p;
- cout<<"Enter read_header() \n";
- read( p, 0);
- cout<<" finish read_header()\n";
- memcpy(&nrecs, &p, 4);
- memcpy(&nitems,((char*)&p)+4, 4);
- cout<<"nrecs= "<<nrecs<<"nitems= "<<nitems<<"\n";
-
- }
-
-
- template<class T>
- void db<T>::update_header(void)
- {
- T p;
-
- memcpy(&p, &nrecs, 4);
- memcpy(((char*)&p)+4, &nitems, 4);
- write(p, 0);
- }
-
-
- template<class T>
- int db<T>::open(char* fname, enum access_mode mode)
- {
-
- cout<<"fname= "<<fname<<endl;
- cout<<"mode= "<<mode<<endl;
- recfile::open(fname, mode);
- cout<<" db::open opened= "<<opened<<"\n";
- if ( opened && mode == f_update )
- read_header();
- return opened;
- }
-
- template<class T>
- int db<T>::close(void)
- {
- if ( opened ) update_header();
- return recfile::close();
- }
-
- template<class T>
- unsigned db<T>::search(T& p)
- {
- unsigned r;
- T q;
- for ( r =1; r<= nrecs; r++ )
- {
- if ( read(q,r) && q.same_key(p) )
- {
- p=q;
- return r;
- }
- }
- return 0;
- }
-
- template<class T>
- unsigned db<T>::add(T& p)
- {
- unsigned r;
- T q;
- r = search(q);
- if ( r )
- {
- if ( write(p,r) )
- {
- nitems++;
- update_header();
- return r;
- }
- }
- else
- {
- if ( write(p, nrecs+1) )
- {
- nrecs++; nitems++;
- update_header();
- return nrecs;
- }
- }
- return 0;
- }
-
-
-
- template<class T>
- unsigned db<T>::del(T& p, unsigned recno)
- {
- unsigned r;
- if ( recno ) r = recno;
- else r = search(p);
- if ( r )
- {
- T q;
- write(q,r);
- nitems--;
- update_header();
- }
- return r;
- }
-
- template<class T>
- unsigned db<T>::update(T& p, unsigned recno)
- {
- unsigned r;
- if ( recno) r = recno;
- else r= search(p);
- if ( r )
- {
- write(p, r);
- }
- return r;
- }
-
-
-
-
- template<class T>
- void db<T>::list(ostream& strm)
- {
- int cur_rec, recs_seen;
- T p;
-
- for ( cur_rec = 1, recs_seen = 0;
- cur_rec <= nrecs && recs_seen < nitems;
- cur_rec++)
- {
- read(p, cur_rec);
- if ( !p.isnull() )
- {
- strm<<p<<"\n";
- recs_seen++;
- }
- }
- }
-
-
-
- // test driver
- void menu(void)
- {
- cout<<"\ndatabase service : \n\n";
- cout<<" c Create database\n";
- cout<<" o Open existing database\n";
- cout<<" f Find part\n";
- cout<<" u Update part\n";
- cout<<" a Add part\n";
- cout<<" d Delete part\n";
- cout<<" l List parts\n";
- cout<<" q Quit\n";
- cout<<" h Help\n\n";
- }
-
-
- int get_action(void)
- {
- char action;
- cout<<" > ";
- cin.clear();
- cin>>action;
- cout<<" action: "<<action<<"\n";
- return action;
- }
-
- int do_action(db<part>& f, int act)
- {
- part p;
- char c, fname[80];
- unsigned rec;
-
- if ( act != 'q' && act != 'c' && act != 'o' &&
- act != 'h' && !f.isopen() )
- {
- cout<< "Database not opened\n";
- return act;
- }
-
- switch(act){
- case 'q': cout<<"Closing down database ...\n";
- f.close();
- break;
- case 'c': cout<<"Enter file name: ";
- cin.get(c);
- cin.get(fname, 80);
- cout<<" c : fname= "<<fname<<endl;
- f.open(fname, f_create);
- break;
-
- case 'o': cout<<"Enter file name: ";
- cin.get(c);
- cin.get(fname, 80);
- f.open(fname, f_update);
- break;
- case 'f': cout<<"find ";
- if ( p.get_key())
- {
- if ( ( rec = f.search(p) ) !=0 )
- {
- cout<<"Part found at rec "<<rec<<"\n";
- cout<<p<<"\n";
- }
- else cout<<"Part not found\n";
- }
- break;
-
- case 'u': cout<<"Update ";
- if ( p.get_key() )
- {
- if ( ( rec=f.search(p) ) != 0 )
- {
- cout<<p<<"\n";
- cout<<"Enetr new part info: \n";
- p.input();
- if ( !p.isnull() )
- {
- if ( f.update(p, rec) )
- cout<<"Part successfully update\n";
- else cout<<"Error updating part\n";
- }
- else cout<<"Part not changed\n";
-
- }
- else cout<<"Part not found\n";
- }
- break;
-
- case 'd': cout<<"Delete ";
- if ( p.get_key() )
- {
- if( ( rec=f.search(p) ) !=0)
- {
- cout<<p<<"\n";
- cout<<"Do you still wish to delete? ";
- cin>>c;
- if ( c=='y' || c=='Y' )
- {
- if ( f.del(p, rec) )
- cout<<"Part deleted\n";
- else cout<<"Error deleting part\n";
- }
-
- else cout<<"Part not deleted\n";
- }
- else cout<<"Part not found\n";
- }
- break;
-
- case 'a': cout<<"Enter part to add below: \n";
- p.input();
- if ( !p.isnull() )
- {
- if ( ( rec=f.add(p) ) != 0 )
- {
- cout<<"Part stored at rec "<<rec<<"\n";
- cout<<p<<"\n";
- }
- }
- break;
-
- case 'l': f.list(cout);
- break;
-
- case 'h': menu();
- break;
- }
- return act;
- }
-
- int main()
- {
- db<part> f;
- int i;
- menu();
- while(1)
- {
- i=get_action();
- if ( i =='q') break;
- do_action(f, i);
- };
- }
-
- % g++ problem.c -o problem
- problem.c:309: template for method `update' doesn't match any in class `db<part>'
- problem.c:309: template for method `del' doesn't match any in class `db<part>'
-
-
-
-
- But, if I change it into the following :
- .
- .
- . ( all the parts of the program is kept the same except : )
- class db: public file_of<part>
- {
- protected:
- unsigned nrecs;
- unsigned nitems;
-
- public:
- db(void): nrecs(0), nitems(0) {}
- void update_header(void);
- void read_header(void);
- int open(char* fname, enum access_mode mode);
- int close(void);
- unsigned search(part& p);
- unsigned add(part& p);
- unsigned del(part& p, unsigned recno=0);
- unsigned update(part& p, unsigned recno=0);
- void list(ostream& strm);
- };
-
- void db::read_header(void)
- {
- part p;
- cout<<"Enter read_header() \n";
- read( p, 0);
- cout<<" finish read_header()\n";
- memcpy(&nrecs, &p, 4);
- memcpy(&nitems,((char*)&p)+4, 4);
- cout<<"nrecs= "<<nrecs<<"nitems= "<<nitems<<"\n";
-
- }
-
-
- void db::update_header(void)
- {
- part p;
-
- memcpy(&p, &nrecs, 4);
- memcpy(((char*)&p)+4, &nitems, 4);
- write(p, 0);
- }
-
-
- int db::open(char* fname, enum access_mode mode)
- {
-
- cout<<"fname= "<<fname<<endl;
- cout<<"mode= "<<mode<<endl;
- recfile::open(fname, mode);
- cout<<" db::open opened= "<<opened<<"\n";
- if ( opened && mode == f_update )
- read_header();
- return opened;
- }
-
- int db::close(void)
- {
- if ( opened ) update_header();
- return recfile::close();
- }
-
- unsigned db::search(part& p)
- {
- unsigned r;
- part q;
- for ( r =1; r<= nrecs; r++ )
- {
- if ( read(q,r) && q.same_key(p) )
- {
- p=q;
- return r;
- }
- }
- return 0;
- }
-
- unsigned db::add(part& p)
- {
- unsigned r;
- part q;
- r = search(q);
- if ( r )
- {
- if ( write(p,r) )
- {
- nitems++;
- update_header();
- return r;
- }
- }
- else
- {
- if ( write(p, nrecs+1) )
- {
- nrecs++; nitems++;
- update_header();
- return nrecs;
- }
- }
- return 0;
- }
-
- unsigned db::del(part& p, unsigned recno)
- {
- unsigned r;
- if ( recno ) r = recno;
- else r = search(p);
- if ( r )
- {
- part q;
- write(q,r);
- nitems--;
- update_header();
- }
- return r;
- }
-
- unsigned db::update(part& p, unsigned recno)
- {
- unsigned r;
- if ( recno) r = recno;
- else r= search(p);
- if ( r )
- {
- write(p, r);
- }
- return r;
- }
-
- void db::list(ostream& strm)
- {
- int cur_rec, recs_seen;
- part p;
-
- for ( cur_rec = 1, recs_seen = 0;
- cur_rec <= nrecs && recs_seen < nitems;
- cur_rec++)
- {
- read(p, cur_rec);
- if ( !p.isnull() )
- {
- strm<<p<<"\n";
- recs_seen++;
- }
- }
- }
-
- .
- .
- .
-
- int main( ){
- db f;
- .
- .
- .
- }
-
- then the program is ok, no compiling errors. I can run it.
- what's the problem? maybe I can not do this? :
-
- template<class T>
- class file_of: public recfile{
- .......... }
-
- template<class T>
- class db: public file_of<T>
- { ........... }
-
-
- if someone can give me the answer , I appreciate it vry much.
- Thanx lot for help in advance.
- my E_Mail : lih@ucunix.san.uc.edu
-