A program I'm trying to compile is simply not working right. I have everything defined the way it should with all the right #include statements there. However, anytime I try to compile with g++, it tells me the functions are undefined. Really, I should not be getting this error. I cannot find anywhere there should/could be a problem. Without posting any code, what could be causing this? I've gone through the code several times myself and checked that all the appropriate files were included where they needed to be included. I'm using g++ 4.2.1 on a Mac OS X 10.6.5 system.

(Not posting code because it's 9 files and the problem shouldn't exist. Even my professor couldn't find a problem with the code. If code is needed, I'll post it.)

Just wait and I'll pull out the crystal ball...Yes please post the code.

Thou shall shake the crystal ball... and here's what shows up

the hw2.cpp file is what I put into the command line when I run g++ hw2.cpp

#include "Server.h"

using namespace std;

int main()
{
	Server ser;
	ser.run();
	return 0;
}

Server.h:

#include <iostream>      
#include <ctime>

#ifndef SERVER
#define SERVER

#include "LQueue.h"  
#include "Client.h"
#include "JSTimer.h"



const int NUM_CATEGORIES = 5;

class Server
{
public:
	Server();
	~Server();
	
	void run();
	
	void display(ostream & out);
	
	void service(int & busyTimeRemaining);
	void checkForNewClient();
	
private:
	
	int    myLengthOfSimulation;
	double myArrivalRate;
	int    myServicePercent[NUM_CATEGORIES];
	
	int    myClientsReceived;
	double myTotalWaitingTime;
	
	JSTimer myTimer;
	
	Queue myIncomingClients;
	
};

#endif

Server.cpp:

#include "Server.h"

using namespace std;

int main()
{
	Server s;
	s.run();
}

Server::Server()
{
	myClientsReceived = 0;
	myTotalWaitingTime = 0;
	cout << "Enter arrival rate (clients per hour): ";
	int clientsPerHour;
	cin >> clientsPerHour;
	myArrivalRate = clientsPerHour / 60.0; 
	
	cout << "Enter percent of clients serviced in\n";
	int percent,
	sum = 0;
	for (int i = 0; i < NUM_CATEGORIES - 1; i++)
	{
		cout << "  <= " << i + 1 << " min. ";      cin >> percent;
		sum += percent;
		myServicePercent[i] = sum;
	}
	myServicePercent[NUM_CATEGORIES - 1] = 100;
	
	cout << "Enter # of minutes to run simulation: ";
	cin >> myLengthOfSimulation;
	
	myTimer.set(myLengthOfSimulation);
	
	long seed = long(time(0));    
	srand(seed);
}

void Server::run()
{
	int busyTimeRemaining = 0;
	while (myTimer.timeRemaining() > 0)
	{
		service(busyTimeRemaining);
		checkForNewClient();
		myTimer.tick();
	}
	cout << "\nNot accepting more calls -- service those waiting\n";
	
	while (!myIncomingClients.empty())
	{
		service(busyTimeRemaining);
		myTimer.tick();
	}
	
	display(cout);
}

void Server::display(ostream & out)
{
	out << "\nNumber of calls processed:   " << myClientsReceived
	<< "\nAve. waiting time per call:  "
	<<      myTotalWaitingTime / myClientsReceived
	<< " minutes" << endl;
}

void Server::service(int & busyTimeRemaining)
{
	if (busyTimeRemaining > 0)        
		busyTimeRemaining--;           
	else
		if (!myIncomingClients.empty())  		{
			Client nextClient = myIncomingClients.front();
			myIncomingClients.dequeue();         
			busyTimeRemaining = nextClient.getServiceTime();
			
			myTotalWaitingTime += 
			nextClient.getArrivalTime() - myTimer.timeRemaining();
		}
}

void Server::checkForNewClient()
{
	int x = rand() % 100;
	
	if (x < 100 * myArrivalRate)
	{
		int r = rand() % 100;
		
		int serviceTime = 0;
		while (r > myServicePercent[serviceTime])
			serviceTime++;
		
		Client newClient(myTimer, serviceTime + 1);
		myIncomingClients.enqueue(newClient);
		myClientsReceived++;
	}
}

Client.h:

/*
 *  Client.h
 *  
 *
 *  Created by Jason Savlov on 11/12/10.
 *  Copyright 2010 Jason Savlov. All rights reserved.
 *
 */

#include <iostream>
#include "JSTimer.h"

using namespace std;

#ifndef CLIENT
#define CLIENT

class Client
{
	
public:
	Client();
	Client(JSTimer & timer, int serviceTime);
	int getArrivalTime();
	int getServiceTime();
	
	friend ostream& operator <<(ostream & os, const Client &aClient);
	
private:
	int myServiceTime;
	int myTimeOfArrival;

		   
};

#endif

Client.cpp:

#include <cassert>
#include "Client.h"

using namespace std;

class Client
{
	
public:
	Client();
	Client(JSTimer & timer, int serviceTime);
	int getArrivalTime();
	int getServiceTime();
	
	friend ostream& operator <<(ostream & os, const Client &aClient);
	
private:
	int myServiceTime;
	int myTimeOfArrival;
	
	
};


Client::Client()
{ 
	myTimeOfArrival = myServiceTime = 0; 
}

Client::Client(const JSTimer & t, int serviceTime)
{
	myTimeOfArrival = t.timeRemaining();
	
	myServiceTime = serviceTime;
}

int Client::getArrivalTime() const
{
	return myTimeOfArrival;
}

int Client::getServiceTime() const
{
	return myServiceTime;
}

void Client::display(ostream & os) const
{
	os << "Arrival Time:    " << myTimeOfArrival << endl
	<< "Service Time:    " << myServiceTime << endl;
}

ostream& operator<<(ostream & os, const Client & aClient)
{
	aClient.display(os);
	return out;
}

JSTimer.h:

#ifndef JSTIMER
#define JSTIMER

class JSTimer
{
public:
	
	JSTimer(int initTime = 0);
	
	void set(int minutes);
	void tick();
	
	int timeRemaining() const;

private:
	int myMinutes;
};

#endif

JSTimer.cpp:

#include <cassert>
using namespace std;
#include "JSTimer.h"


JSTimer::JSTimer(int initTime)
{
	assert(initTime >= 0);
	myMinutes = initTime;
}

void JSTimer::set(int minutes)
{
	assert(minutes >= 0);
	myMinutes = minutes;
}

void JSTimer::tick()
{
	myMinutes--;
}

int JSTimer::timeRemaining() const
{
	return myMinutes;
}

LQueue.h:

#include <iostream>
#include "Client.h"

#ifndef LQUEUE
#define LQUEUE

typedef Client QueueElement;

class Queue
{
 public:


  Queue();

  Queue(const Queue & original);
  
  ~Queue(); 

 const Queue & operator= (const Queue & rightHandSide);


  bool empty() const;


  void enqueue(const QueueElement & value);
  

  void display(ostream & out) const;
 

  QueueElement front() const;
 

  void dequeue();
  
 private:
   class Node
   {
    public:
      QueueElement data;
      Node * next;
      Node(QueueElement value, Node * link = 0)
	  { data = value; next = link; }

  };

  typedef Node * NodePointer;

  NodePointer myFront,      
	myBack;       
	
};
#endif

LQueue.cpp:

#include <new>
using namespace std;

#include "LQueue.h"

Queue::Queue()
: myFront(0), myBack(0)
{}

Queue::Queue(const Queue & original)
{
   myFront = myBack = 0;
   if (!original.empty())
   {
      myFront = myBack = new Queue::Node(original.front());

      // Set pointer to run through original's linked list
      Queue::NodePointer origPtr = original.myFront->next;
      while (origPtr != 0)
      {
         myBack->next = new Queue::Node(origPtr->data);
         myBack = myBack->next;
         origPtr = origPtr->next;
      }
   }
}

//--- Definition of Queue destructor
Queue::~Queue()
{ 
  // Set pointer to run through the queue
  Queue::NodePointer prev = myFront,
                     ptr;
  while (prev != 0)
    {
      ptr = prev->next;
      delete prev;
      prev = ptr;
    }
}

//--- Definition of assignment operator
const Queue & Queue::operator=(const Queue & rightHandSide)
{
   if (this != &rightHandSide)         // check that not q = q
   {
      this->~Queue();                  // destroy current linked list
      if (rightHandSide.empty())       // empty queue
         myFront = myBack = 0;
      else
      {                                // copy rightHandSide's list
         // Copy first node
         myFront = myBack = new Queue::Node(rightHandSide.front());

         // Set pointer to run through rightHandSide's linked list
         Queue::NodePointer rhsPtr = rightHandSide.myFront->next;
         while (rhsPtr != 0)
         {
           myBack->next = new Queue::Node(rhsPtr->data);
           myBack = myBack->next;
           rhsPtr = rhsPtr->next;
         }
      }
   }
   return *this;
}

//--- Definition of empty()
bool Queue::empty() const
{ 
   return (myFront == 0); 
}

//--- Definition of enqueue()
void Queue::enqueue(const QueueElement & value)
{
   Queue::NodePointer newptr = new Queue::Node(value);
   if (empty())
      myFront = myBack = newptr;
   else
   {
      myBack->next = newptr;
      myBack = newptr;
   }
}

//--- Definition of display()
void Queue::display(ostream & out) const
{
   Queue::NodePointer ptr;
   for (ptr = myFront; ptr != 0; ptr = ptr->next)
     out << ptr->data << "  ";
   out << endl;

}

//--- Definition of front()
QueueElement Queue::front() const
{
   if (!empty())
      return (myFront->data);
   else
   {
      cerr << "*** Queue is empty "
              " -- returning garbage ***\n";
      QueueElement * temp = new(QueueElement);  
      QueueElement garbage = *temp;     // "Garbage" value
      delete temp;
      return garbage;
   }
}

//--- Definition of dequeue()
void Queue::dequeue()
{
   if (!empty())
   {
      Queue::NodePointer ptr = myFront;
      myFront = myFront->next;
      delete ptr;
      if (myFront == 0)     // queue is now empty
         myBack = 0;
   }   
   else
      cerr << "*** Queue is empty -- can't remove a value ***\n";
}

There's the code.

Well I tried to compile your client program and got this...

g++ client.cpp JSTimer.o -Wall -ansi -pedantic -o client

client.cpp:30: error: prototype for ‘Client::Client(const JSTimer&, int)’ does not match any in class ‘Client’
client.cpp:7: error: candidates are: Client::Client(const Client&)
client.cpp:11: error: Client::Client(JSTimer&, int)
client.cpp:25: error: Client::Client()
client.cpp:37: error: prototype for ‘int Client::getArrivalTime() const’ does not match any in class ‘Client’
client.cpp:12: error: candidate is: int Client::getArrivalTime()
client.cpp:42: error: prototype for ‘int Client::getServiceTime() const’ does not match any in class ‘Client’
client.cpp:13: error: candidate is: int Client::getServiceTime()
client.cpp:47: error: no ‘void Client::display(std::ostream&) const’ member function declared in class ‘Client’
client.cpp: In function ‘std::ostream& operator<<(std::ostream&, const Client&)’:
client.cpp:55: error: ‘const class Client’ has no member named ‘display’
client.cpp:56: error: ‘out’ was not declared in this scope

If you correct your errors, I'm pretty sure g++ will link correctly.

Edited 5 Years Ago by gerard4143: n/a

Sorry I am not impressed with your teacher.

Most compilers of c++ and a lot of other compiled language split the program up into individual files. Each of those files are normally compiled into object files.
These normally have the .o extension. They are the machine code of each block of code. However, in many of these .cpp file, there is a call to a function that is declared (normally in a .h file), but not defined (the actual code for a function, in a .cpp file. The object file contains a symbolic link to that function but not a direct call. These is resolved by the linker that takes all the .o files and tries to resolve all the symbolic links to produce a single executable.

Normally the production of an object file is done first, and then the object files are linked together. The commands given would be

g++ -c Client.cpp
g++ -c Server.cpp
// All the other .cpp files etc....

The you would link it with the command g++ Server.o Client.o other.o and that would give you an executable called a.out. [if you used the -o option you can change that name]

However, for short programs, there is a quick way, just give g++ the list of files to compile and it will compile and link them .

Your command line was : g++ hw2.cpp

So unfortunately the linker says that it cannot link the files because it doesn't know lots and lots of
however, in almost all modern compilers,

The program does not compile, as given, errors include, additional copy of the client class definition, mis-matching declarations, e.g const missing from the getXX() functions in Client.

Server.cpp : missing #include <cstdlib> from the file.

You have two copies of int main(), hw2.cpp AND in Server.cpp which you need for hw2.cpp.

you have not written the Server destructor, but have defined it.

hopefully, that will give you enough to start debugging..

Comments
Thoroughly explained (Y)

With the help of you guys, I got this to work. Thank you for the helpful posts! :)

Edited 5 Years Ago by jsav: n/a

This question has already been answered. Start a new discussion instead.