I keep getting loads of linker errors that probably have something to do with virtual-functions/definitions and/or static class members...
I've seen several relevant posts but none of the solutions suggested work,
can you see wht the problem is here?
My projects consists of 3 files:
BALLS.H
#include <iostream>
using namespace std;
class Ball{ //Abstract Class!!
protected: //no Balls will be constructed
int durability;
bool hidden;
public:
Ball(int dur=0) :durability(dur), hidden(false){}
virtual void hit(){}
virtual void rest()=0;
virtual int get_state() {}
};
class Basket : public Ball {
public:
Basket(int L1) :Ball(L1)
{ cout<<"New basketball!"<<endl;
count++;
}
void rest(){}
int get_state();
void hit();
static int count;
};
class Tennis : public Ball {
public:
Tennis(int L2) :Ball(L2)
{ cout<<"New tennis ball!"<<endl;
count++;
}
void rest(){ Ball::durability=Ball::durability+3; }
int get_state();
void hit();
static int count;
};
class Ping_pong : public Ball {
private:
bool broken;
public:
Ping_pong(int L3) :Ball(L3), broken(false)
{ cout<<"New ping-pong ball!"<<endl;
count++;
}
void rest(){ Ball::durability++; }
int get_state();
void hit();
static int count;
};
BALLS.CPP
#include <iostream>
#include <cstdlib>
#include "Balls.h"
using namespace std;
void Basket::hit(){
int to_hell;
if(!hidden){
if(durability){
if(!(to_hell=rand()%2)){
cout<<"Tsaf!"<<endl;
durability--;
}
else{
cout<<"Oh, what a hit! The ball is gone!"<<endl;
hidden=true;
}
}
else
cout<<"Plof!"<<endl;
}
else
cout<<"You cannot hit a hidden ball!"<<endl;
}
void Tennis::hit(){
int to_hell;
if(!hidden){
if(durability){
if(!(to_hell=rand()%2)){
cout<<"Tsaf!"<<endl;
durability=durability-5;
if(durability<0) durability=0;
}
else{
cout<<"Oh, what a hit! The ball is gone!"<<endl;
hidden=true;
}
}
else
cout<<"Plof!"<<endl;
}
else
cout<<"You cannot hit a hidden ball!"<<endl;
}
void Ping_pong::hit(){
int to_hell, sudn_brk;
if(!broken){
if(!hidden){
if(durability){
if(!(to_hell=rand()%2)){
cout<<"Tsaf!"<<endl;
if(!(sudn_brk=rand()%2)){
durability--;;
if(durability<0) durability=0;
}
else{
cout<<"Bam! Ball broken!"<<endl;
broken=true;
}
}
else{
cout<<"Oh, what a hit! The ball is gone!"<<endl;
hidden=true;
}
}
else
cout<<"Plof!"<<endl;
}
else
cout<<"You cannot hit a hidden ball!"<<endl;
}
else
cout<<"No point trying to hit a broken ball!"<<endl;
}
int Basket::get_state(){
if(hidden){
count--;
return -1;
}
if(!durability) count--;
return durability;
}
int Tennis::get_state(){
if(hidden){
count--;
return -1;
}
if(!durability) count--;
return durability;
}
int Ping_pong::get_state(){
if(hidden){
count--;
return -1;
}
if(broken){
count--;
return -2;
}
if(!durability) count--;
return durability;
}
and MAIN.CPP to test my model
#include <iostream>
#include <cstdlib>
#include <cctype>
#include <string>
#include "Balls.h"
using namespace std;
int main(int argc, char* argv[]){
if(argc!=6){
cout<<"Wrong number of arguments given"<<endl;
return 0;
}
else{
int L1,L2,L3,N,K; //Managing command line arguments
L1=atoi(argv[1]);
L2=atoi(argv[2]);
L3=atoi(argv[3]);
N=atoi(argv[4]);
K=atoi(argv[5]);
if(!((0<L3)&&(L3<L2)&&(L2<L1))){ //Cheching for durability requirements
cout<<"Initial durabilities should be specifically sorted"
<<"and positive (no worn-out balls from scratch)"<<endl;
return 0;
}
srand(time(NULL));
Basket::count=0;
Tennis::count=0;
Ping_pong::count=0;
cout<<"So let's get "<<N<<" balls.."<<endl; //Creating an array of NULL pointers
Ball** Inventory= new Ball*[N];
int i;
for(i=0;i<N;i++){ //Dereferencing each pointer to
// newely created random-typed Balls
int type=rand()%3+1;
switch(type){
case 1:
Inventory[i]=new Basket(L1);
break;
case 2:
Inventory[i]=new Tennis(L2);
break;
case 3:
Inventory[i]=new Ping_pong(L3);
break;
}
}
int choice;
int state;
Ball *p;
cout<<"Now let's hit some balls!"<<endl;
for(i=0;i<K;i++){ //In each of the K rounds...
choice=rand()%N+1;
cout<<"Ball #"<<choice<<" chosen for the hit..."<<endl;
p=Inventory[choice-1];
p->hit(); //...select and hit a random ball...
int j;
for(j=0;j<N;j++){ //...and give the others a break
p=Inventory[j];
if(j!=choice-1) p->rest();
}
for(j=0;j<N;j++){ //Eventually, print-out each ball's condition
p=Inventory[j];
state=p->get_state();
if(state==-1) cout<<"Ball #"<<j+1<<" hidden!"<<endl;
else if(state==-2) cout<<"Ball #"<<j+1<<" broken!"<<endl;
else cout<<"Ball #"<<j+1<<" has "<<state<<" durability"<<endl;
}
}
int b_count=Basket::count; //After the hit sessions, count the balls left for each type
int t_count=Tennis::count;
int p_count=Ping_pong::count;
int max=b_count; //...and find the fittest...
string sport="Basket";
if(t_count>max){
max=t_count;
sport="Tennis";
}
if(p_count>max){
max=p_count;
sport="Ping pong";
}
cout<<"Since we have the most balls left ("<<max //...to choose our afternoon pastime!
<<")... Let's play "<<sport<<'!'<<endl;
return 1;
}
}
and then
linux10:/home/users/sdi1200184/askhseis/ask3/ver3.0(static_counts)>
linux10:/home/users/sdi1200184/askhseis/ask3/ver3.0(static_counts)>g++ -o test m ain.cpp Balls.cpp
/tmp/ccFII2FB.o: In function `main':
main.cpp:(.text+0x112): undefined reference to `Basket::count'
main.cpp:(.text+0x11c): undefined reference to `Tennis::count'
main.cpp:(.text+0x126): undefined reference to `Ping_pong::count'
main.cpp:(.text+0x4e1): undefined reference to `Basket::count'
main.cpp:(.text+0x4ea): undefined reference to `Tennis::count'
main.cpp:(.text+0x4f3): undefined reference to `Ping_pong::count'
/tmp/ccFII2FB.o: In function `Basket::Basket(int)':
main.cpp:(.text._ZN6BasketC2Ei[_ZN6BasketC5Ei]+0x46): undefined reference to `Ba sket::count'
main.cpp:(.text._ZN6BasketC2Ei[_ZN6BasketC5Ei]+0x4e): undefined reference to `Ba sket::count'
/tmp/ccFII2FB.o: In function `Tennis::Tennis(int)':
main.cpp:(.text._ZN6TennisC2Ei[_ZN6TennisC5Ei]+0x46): undefined reference to `Te nnis::count'
main.cpp:(.text._ZN6TennisC2Ei[_ZN6TennisC5Ei]+0x4e): undefined reference to `Te nnis::count'
/tmp/ccFII2FB.o: In function `Ping_pong::Ping_pong(int)':
main.cpp:(.text._ZN9Ping_pongC2Ei[_ZN9Ping_pongC5Ei]+0x4d): undefined reference to `Ping_pong::count'
main.cpp:(.text._ZN9Ping_pongC2Ei[_ZN9Ping_pongC5Ei]+0x55): undefined reference to `Ping_pong::count'
/tmp/ccLOf5p1.o: In function `Basket::get_state()':
Balls.cpp:(.text+0x3b3): undefined reference to `Basket::count'
Balls.cpp:(.text+0x3bb): undefined reference to `Basket::count'
Balls.cpp:(.text+0x3d1): undefined reference to `Basket::count'
Balls.cpp:(.text+0x3d9): undefined reference to `Basket::count'
/tmp/ccLOf5p1.o: In function `Tennis::get_state()':
Balls.cpp:(.text+0x3f5): undefined reference to `Tennis::count'
Balls.cpp:(.text+0x3fd): undefined reference to `Tennis::count'
Balls.cpp:(.text+0x413): undefined reference to `Tennis::count'
Balls.cpp:(.text+0x41b): undefined reference to `Tennis::count'
/tmp/ccLOf5p1.o: In function `Ping_pong::get_state()':
Balls.cpp:(.text+0x437): undefined reference to `Ping_pong::count'
Balls.cpp:(.text+0x43f): undefined reference to `Ping_pong::count'
Balls.cpp:(.text+0x456): undefined reference to `Ping_pong::count'
Balls.cpp:(.text+0x45e): undefined reference to `Ping_pong::count'
Balls.cpp:(.text+0x474): undefined reference to `Ping_pong::count'
/tmp/ccLOf5p1.o:Balls.cpp:(.text+0x47c): more undefined references to `Ping_pong ::count' follow
collect2: ld returned 1 exit status
linux10:/home/users/sdi1200184/askhseis/ask3/ver3.0(static_counts)>