User Name Password Register
DaniWeb IT Discussion Community
All
What is DaniWeb IT Discussion Community?
You're currently browsing the C++ section within the Software Development category of DaniWeb, a massive community of 401,682 software developers, web developers, Internet marketers, and tech gurus who are all enthusiastic about making contacts, networking, and learning from each other. In fact, there are 3,568 IT professionals currently interacting right now! Registration is free, only takes a minute and lets you enjoy all of the interactive features of the site.
Views: 1791 | Replies: 3
Reply
Join Date: Jun 2005
Location: Germany
Posts: 62
Reputation: freemind is an unknown quantity at this point 
Rep Power: 4
Solved Threads: 1
freemind's Avatar
freemind freemind is offline Offline
Junior Poster in Training

Abstract Class member function problem

  #1  
Jul 29th, 2005
Hi to everybody! Here I paste some simple exercise code that I wrote. The errors are pasted from the compiler log at the end of the source code. The add() function looks ok to me and I can't understand what the compiler wants from me :o Thanks!

 
#include <iostream>
#include <string>
#include <list>
using namespace std; 
class Worker {
	  protected:
			  string fname, lname;
			  string address;
			  unsigned number;
	  public:
			 inline virtual void add(DepBoss* new_boss, list<Worker*>& M) = 0;
			 inline virtual void print(void) {
					 cout << " Name: " << fname << " " << lname;
					 cout << " Address: " << address;
					 cout << " Number: " << number;
			 }
			 Worker(string fn, string ln, string addr, unsigned n)
						   :fname((string)fn), lname((string)ln), address((string)addr) {
					if(n < 0)
						 throw "Scheisse in Worker Constructor!";
					else
						 number = n;
			 };
			 virtual ~Worker(){};
};
class DepBoss : public Worker {
	  private:
			  short level;
			  int   podchineni;
	  public:
			 inline virtual void add(DepBoss* new_boss, list<Worker*>& M);
			 inline virtual void print(void);
			 DepBoss(string fn, string ln, string addr, unsigned n, short lvl, int pod)
							:Worker(fn, ln, addr, n) {
							
					 if(lvl < 0 && lvl > 5)
							throw "Scheisse in DepBoss Constructor(lvl)";
					 else
							level = lvl;
					 if(pod < 0 && pod > 100)
							throw "Scheisse in DepBoss Constructor(pod)";
					 else
							podchineni = pod;
			 };
			 virtual ~DepBoss(){};
};
inline void DepBoss::add(DepBoss* new_boss, list<Worker*>& M) {
			   M.push_front(new_boss);
}
void DepBoss::print(void) {
	 cout << " DepBosses:" << endl;
	 Worker::print();
	 cout << "\n Level of clearance: " << level;
	 cout << "\n Number of podchineni: " << podchineni;
}
void print_list(list<Worker*>& w) {
	 for(list<Worker*>::const_iterator I=w.begin(); I!=w.end(); ++I)
			  (*I)->print();
}
int main(void) {
	static string fn, ln, addr;
	static unsigned num;
	static short lvl;
	static int pod;
	
	try {		  
			   cout << "\n Please, input first name: "; cin >> fn;
			   cout << "\n Please, input last name : "; cin >> ln;
			   cout << "\n Please, input DepBoss' address: "; cin >> addr;
			   cout << "\n Please, input DepBoss' number: "; cin >> num;
			   cout << "\n Please, input DepBoss' clearance level: "; cin >> lvl;
			   cout << "\n Please, input DepBoss' number of podchineni: "; cin >> pod;
	
			   DepBoss Boss("Toni", "Montana", "Cubastr. 13", 1, 0, 50);
			   list<Worker*> L;
			   L.push_front(&Boss);
			   DepBoss* Boss2 = new DepBoss(fn, ln, addr, num, lvl, pod);
			   Boss2->add(Boss2, L);
			   print_list(L);
			   delete Boss2;
	}
	catch(char *str) {
				cout << "\n Erroroneus inputs given: " << str << ".... Exiting." << endl;
				return -1;
	}
	
	return 0;
}
/*
tbook.cpp:13: error: variable or field `add' declared void
tbook.cpp:13: error: `add' declared as a `virtual' field
tbook.cpp:13: error: `add' declared as an `inline' field
tbook.cpp:13: error: expected `;' before '(' token
make.exe: *** [tbook.o] Error 1
Execution terminated
*/
AddThis Social Bookmark Button
Reply With Quote  
Join Date: Jul 2005
Location: Long Island, NY
Posts: 2
Reputation: TomcatMCAD is an unknown quantity at this point 
Rep Power: 0
Solved Threads: 0
TomcatMCAD's Avatar
TomcatMCAD TomcatMCAD is offline Offline
Newbie Poster

Re: Abstract Class member function problem

  #2  
Jul 29th, 2005
Hello Freemind:

I took a look at your code and actually attempted to run it in an empty default Visual Studio 6 project. It didn't compile but with different errors. The errors I recieved were around the 'add' function as well however.

Anyhow, with only a minor change I was able to compile and run your program. All I did was change the following three lines to use the base 'Worker' class instead of the derivied 'DepBoss' class: (each bold line replaces the line above it)

 
#include <iostream>
#include <string>
#include <list>
using namespace std; 
class Worker {
	  protected:
			  string fname, lname;
			  string address;
			  unsigned number;
	  public:
			 //inline virtual void add(DepBoss* new_boss, list<Worker*>& M) = 0;
			 inline virtual void add(Worker* new_boss, list<Worker*>& M) = 0;
			 inline virtual void print(void) {
					 cout << " Name: " << fname << " " << lname;
					 cout << " Address: " << address;
					 cout << " Number: " << number;
			 }
			 Worker(string fn, string ln, string addr, unsigned n)
						   :fname((string)fn), lname((string)ln), address((string)addr) {
					if(n < 0)
						 throw "Scheisse in Worker Constructor!";
					else
						 number = n;
			 };
			 virtual ~Worker(){};
};
class DepBoss : public Worker {
	  private:
			  short level;
			  int   podchineni;
	  public:
			 //inline virtual void add(DepBoss* new_boss, list<Worker*>& M);
			 inline virtual void add(Worker* new_boss, list<Worker*>& M);
			 inline virtual void print(void);
			 DepBoss(string fn, string ln, string addr, unsigned n, short lvl, int pod)
							:Worker(fn, ln, addr, n) {
							
					 if(lvl < 0 && lvl > 5)
							throw "Scheisse in DepBoss Constructor(lvl)";
					 else
							level = lvl;
					 if(pod < 0 && pod > 100)
							throw "Scheisse in DepBoss Constructor(pod)";
					 else
							podchineni = pod;
			 };
			 virtual ~DepBoss(){};
};
//inline void DepBoss::add(DepBoss* new_boss, list<Worker*>& M) 
inline void DepBoss::add(Worker* new_boss, list<Worker*>& M) {
			   M.push_front(new_boss);
}
void DepBoss::print(void) {
	 cout << " DepBosses:" << endl;
	 Worker::print();
	 cout << "\n Level of clearance: " << level;
	 cout << "\n Number of podchineni: " << podchineni;
}
void print_list(list<Worker*>& w) {
	 for(list<Worker*>::const_iterator I=w.begin(); I!=w.end(); ++I)
			  (*I)->print();
}
int main(void) {
	static string fn, ln, addr;
	static unsigned num;
	static short lvl;
	static int pod;
	
	try {		  
			   cout << "\n Please, input first name: "; cin >> fn;
			   cout << "\n Please, input last name : "; cin >> ln;
			   cout << "\n Please, input DepBoss' address: "; cin >> addr;
			   cout << "\n Please, input DepBoss' number: "; cin >> num;
			   cout << "\n Please, input DepBoss' clearance level: "; cin >> lvl;
			   cout << "\n Please, input DepBoss' number of podchineni: "; cin >> pod;
	
			   DepBoss Boss("Toni", "Montana", "Cubastr. 13", 1, 0, 50);
			   list<Worker*> L;
			   L.push_front(&Boss);
			   DepBoss* Boss2 = new DepBoss(fn, ln, addr, num, lvl, pod);
			   Boss2->add(Boss2, L);
			   print_list(L);
			   delete Boss2;
	}
	catch(char *str) {
				cout << "\n Erroroneus inputs given: " << str << ".... Exiting." << endl;
				return -1;
	}
	
	return 0;
}
/*
tbook.cpp:13: error: variable or field `add' declared void
tbook.cpp:13: error: `add' declared as a `virtual' field
tbook.cpp:13: error: `add' declared as an `inline' field
tbook.cpp:13: error: expected `;' before '(' token
make.exe: *** [tbook.o] Error 1
Execution terminated
*/

The reason I think the compiler was complaining is because you cannot use a derived class in a base class as you did. You can however use an instance of, or in this example a pointer to, a base class in derived classes.

Hope this helps, and if you would like a copy of the 'mini project' I created, let me know. Good luck!

Incidently, here was the ouput of the program:

Please, input first name: Michael

Please, input last name : R

Please, input DepBoss' address: Bayview

Please, input DepBoss' number: 11111

Please, input DepBoss' clearance level: 2

Please, input DepBoss' number of podchineni: 5
DepBosses:
Name: Michael R Address: Bayview Number: 11111
Level of clearance: 2
Number of podchineni: 5 DepBosses:
Name: Toni Montana Address: Cubastr. 13 Number: 1
Level of clearance: 0
Number of podchineni: 50
Reply With Quote  
Join Date: Jun 2005
Location: Germany
Posts: 62
Reputation: freemind is an unknown quantity at this point 
Rep Power: 4
Solved Threads: 1
freemind's Avatar
freemind freemind is offline Offline
Junior Poster in Training

Re: Abstract Class member function problem

  #3  
Jul 29th, 2005
Originally Posted by TomcatMCAD
Hello Freemind:

I took a look at your code and actually attempted to run it in an empty default Visual Studio 6 project. It didn't compile but with different errors. The errors I recieved were around the 'add' function as well however.

Anyhow, with only a minor change I was able to compile and run your program. All I did was change the following three lines to use the base 'Worker' class instead of the derivied 'DepBoss' class: (each bold line replaces the line above it)

 
#include <iostream>
#include <string>
#include <list>
using namespace std; 
class Worker {
	 protected:
			 string fname, lname;
			 string address;
			 unsigned number;
	 public:
			 //inline virtual void add(DepBoss* new_boss, list<Worker*>& M) = 0;
			 inline virtual void add(Worker* new_boss, list<Worker*>& M) = 0;
			 inline virtual void print(void) {
					 cout << " Name: " << fname << " " << lname;
					 cout << " Address: " << address;
					 cout << " Number: " << number;
			 }
			 Worker(string fn, string ln, string addr, unsigned n)
						 :fname((string)fn), lname((string)ln), address((string)addr) {
					if(n < 0)
						 throw "Scheisse in Worker Constructor!";
					else
						 number = n;
			 };
			 virtual ~Worker(){};
};
class DepBoss : public Worker {
	 private:
			 short level;
			 int podchineni;
	 public:
			 //inline virtual void add(DepBoss* new_boss, list<Worker*>& M);
			 inline virtual void add(Worker* new_boss, list<Worker*>& M);
			 inline virtual void print(void);
			 DepBoss(string fn, string ln, string addr, unsigned n, short lvl, int pod)
							:Worker(fn, ln, addr, n) {
 
					 if(lvl < 0 && lvl > 5)
							throw "Scheisse in DepBoss Constructor(lvl)";
					 else
							level = lvl;
					 if(pod < 0 && pod > 100)
							throw "Scheisse in DepBoss Constructor(pod)";
					 else
							podchineni = pod;
			 };
			 virtual ~DepBoss(){};
};
//inline void DepBoss::add(DepBoss* new_boss, list<Worker*>& M) 
inline void DepBoss::add(Worker* new_boss, list<Worker*>& M) {
			 M.push_front(new_boss);
}
void DepBoss::print(void) {
	 cout << " DepBosses:" << endl;
	 Worker::print();
	 cout << "\n Level of clearance: " << level;
	 cout << "\n Number of podchineni: " << podchineni;
}
void print_list(list<Worker*>& w) {
	 for(list<Worker*>::const_iterator I=w.begin(); I!=w.end(); ++I)
			 (*I)->print();
}
int main(void) {
	static string fn, ln, addr;
	static unsigned num;
	static short lvl;
	static int pod;
 
	try {		 
			 cout << "\n Please, input first name: "; cin >> fn;
			 cout << "\n Please, input last name : "; cin >> ln;
			 cout << "\n Please, input DepBoss' address: "; cin >> addr;
			 cout << "\n Please, input DepBoss' number: "; cin >> num;
			 cout << "\n Please, input DepBoss' clearance level: "; cin >> lvl;
			 cout << "\n Please, input DepBoss' number of podchineni: "; cin >> pod;
 
			 DepBoss Boss("Toni", "Montana", "Cubastr. 13", 1, 0, 50);
			 list<Worker*> L;
			 L.push_front(&Boss);
			 DepBoss* Boss2 = new DepBoss(fn, ln, addr, num, lvl, pod);
			 Boss2->add(Boss2, L);
			 print_list(L);
			 delete Boss2;
	}
	catch(char *str) {
				cout << "\n Erroroneus inputs given: " << str << ".... Exiting." << endl;
				return -1;
	}
 
	return 0;
}
/*
tbook.cpp:13: error: variable or field `add' declared void
tbook.cpp:13: error: `add' declared as a `virtual' field
tbook.cpp:13: error: `add' declared as an `inline' field
tbook.cpp:13: error: expected `;' before '(' token
make.exe: *** [tbook.o] Error 1
Execution terminated
*/

The reason I think the compiler was complaining is because you cannot use a derived class in a base class as you did. You can however use an instance of, or in this example a pointer to, a base class in derived classes.

Hope this helps, and if you would like a copy of the 'mini project' I created, let me know. Good luck!

Incidently, here was the ouput of the program:


Thanks for the answer and the time that you took! However the program runs quite fine with the minor change of adding the line "class DepBoss;" before "class Worker {...}" (special thanks to zyrus).
Reply With Quote  
Join Date: Jul 2005
Location: Long Island, NY
Posts: 2
Reputation: TomcatMCAD is an unknown quantity at this point 
Rep Power: 0
Solved Threads: 0
TomcatMCAD's Avatar
TomcatMCAD TomcatMCAD is offline Offline
Newbie Poster

Re: Abstract Class member function problem

  #4  
Jul 29th, 2005
Originally Posted by freemind
Thanks for the answer and the time that you took! However the program runs quite fine with the minor change of adding the line "class DepBoss;" before "class Worker {...}" (special thanks to zyrus).

You can do that, and it will work, but what would be the point of creating a base class - derived class scenario like the one you did where functions in the base class only accept a single type of derived class. It seems somewhat paradoxal, like a parent needing to know about his child in order create his child.

also, Since the Worker class contains a function that uses DepBoss, which inturn is derived from Worker, how could one ever really create another usable derived class, say for instance 'class Employee : public Worker'. I understand that you can get the compiler to accept another derived class but from a structural point of view... you couldn't do much with it. and if thats the case... why not create one single class instead of using inhertance.

It seems like the solution of predefining the derived class so you can use it specifically in the base class, while syntactically correct, may still not necessarily be the correct answer from a design point of view and to that end, I'm curious to know what else if anything you intend to do with the program and how your Worker and DepBoss classes will fit into those plans.

-Michael
Reply With Quote  
Reply

Only community members can participate in forum threads. You must register or log in to contribute.

DaniWeb C++ Marketplace
Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)

 

Thread Tools Display Modes

Similar Threads
Other Threads in the C++ Forum

All times are GMT -4. The time now is 7:39 am.
Forum system based on vBulletin Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
©2003 - 2008 DaniWeb® LLC