I currently have a template class, another class that is passed as the parameter to the template and a driver and I am getting these errors, I have no clue what the problem is. Also I have another issue with this project I need to sort out which is insert an item into the list so the list is always in ascending order. But I want to sort these undefined references first

Errors:

[The.Viking@The proj4]$ make
[The.Viking@The proj4]$ make
g++ -c ballTeam.cpp
g++ -c arrayListTypeT.cpp
g++ -c proj4.cpp
g++ -o proj4 *.o
proj4.o: In function `main':
proj4.cpp:(.text+0x21): undefined reference to `arrayListTypeT<ballTeam>::arrayListTypeT(int)'
proj4.cpp:(.text+0xf0): undefined reference to `arrayListTypeT<ballTeam>::insert(ballTeam)'
proj4.cpp:(.text+0x1a4): undefined reference to `arrayListTypeT<ballTeam>::~arrayListTypeT()'
proj4.cpp:(.text+0x1c5): undefined reference to `arrayListTypeT<ballTeam>::~arrayListTypeT()'
collect2: ld returned 1 exit status

Template Class Implementation

// Implementation of the templated version of arrayListType
#include <iostream>
#include <cassert>
#include "arrayListTypeT.h"

using namespace std;

template<class elemType>
bool arrayListTypeT<elemType>::isEmpty() const
{ return (length == 0); }

template<class elemType>
bool arrayListTypeT<elemType>::isFull() const
{ return (length == maxSize); }

template<class elemType>
int arrayListTypeT<elemType>::listSize() const
{ return length; }

template<class elemType>
int arrayListTypeT<elemType>::maxListSize() const
{ return maxSize; }

template<class elemType>
void arrayListTypeT<elemType>::print() const
{
	for (int i = 0; i < length; i++)
		cout << list[i] << " ";
	cout << endl;
}

template<class elemType>
bool arrayListTypeT<elemType>::isItemAtEqual(int location, elemType item) const
{ return(list[location] == item); }

template<class elemType>
void arrayListTypeT<elemType>::removeAt(int location)
{
	if (location < 0 || location >= length)
    	cout << "The location of the item to be removed "
			 << "is out of range." << endl;
	else
	{
   		for (int i = location; i < length - 1; i++)
	 		list[i] = list[i+1];
		length--;
	}
} //end removeAt

template<class elemType>
void arrayListTypeT<elemType>::retrieveAt(int location, elemType& retItem)
{
	if (location < 0 || location >= length)
    	cout << "The location of the item to be retrieved is "
			 << "out of range." << endl;
	else
		retItem = list[location];
} // retrieveAt

template<class elemType>
void arrayListTypeT<elemType>::replaceAt(int location, elemType repItem)
{
	if (location < 0 || location >= length)
    	cout << "The location of the item to be replaced is "
			 << "out of range." << endl;
	else
		list[location] = repItem;

} //end replaceAt

template<class elemType>
void arrayListTypeT<elemType>::clearList()
{
	length = 0;
} // end clearList

template<class elemType>
arrayListTypeT<elemType>::arrayListTypeT(int size)
{
    if (size <= 0)
    {
        cout << "The array size must be positive. Creating "
             << "an array of size 100. " << endl;
        maxSize = 100;
    }
    else
        maxSize = size;
    length = 0;
    list = new elemType[maxSize];
    assert(list != NULL);
}

template<class elemType>
arrayListTypeT<elemType>::~arrayListTypeT<elemType>()
{ delete [] list; }

template<class elemType>
arrayListTypeT<elemType>::arrayListTypeT(const arrayListTypeT<elemType>& otherList)
{
    maxSize = otherList.maxSize;
    length = otherList.length;
    list = new elemType[maxSize];  //create the array
    assert(list != NULL);          //terminate if unable to allocate

    for (int j = 0; j < length; j++)  //copy otherList
        list [j] = otherList.list[j];
}//end copy constructor

template<class elemType>
int arrayListTypeT<elemType>::seqSearch(elemType item)  const
{
	int i;
	for (i = length - 1; i >= 0; i--)
	   if (list[i] == item)
	   { break; }
	return i;
} //end seqSearch

template<class elemType>
void arrayListTypeT<elemType>::insert(elemType insertItem)
{
  // Your code to insert a new item into the list goes here.
  // You are required to check for the following errors:
  // Duplicate insertion.
  // Full list.
  // If either error occurs, display an appropriate message leave the 
  // list unchanged.
  
  
  if(isFull())
     cout<<"Cannot insert item, list is full.\n"<<endl;
   
   for(int i = 0; i < length; i++)
   {
     if(list[i] = insertItem)
     {
       cout<<"Duplicate Item in list\n"<<endl;
       break;
     }
     else
     {
        list[length] = insertItem;
        length++;
     }
   }
} //end insert

template<class elemType>
void arrayListTypeT<elemType>::remove(elemType removeItem)
{
	int loc;
	if (length == 0)
		cout << "Cannot delete from an empty list." << endl;
	else
	{
		loc = seqSearch(removeItem);

		if (loc != -1)
			removeAt(loc);
		else
			cout << "The team to be deleted is not in the list."
				 << endl;
	}
} //end remove

Class being passed as parameter to template

#include <iostream>
#include "ballTeam.h"
using namespace std;

ballTeam::ballTeam()
{
  name = "";
  wins = 0;
  losses = 0;
  totalPoints = 0;
}

ballTeam::ballTeam(string tName, int tWins, int tLosses, int tTotal)
{
  name = tName;
  wins = tWins;
  losses = tLosses;
  totalPoints = tTotal;
}

void ballTeam::set(string tName, int tWins, int tLosses, int tTotal)
{
  name = tName;
  wins = tWins;
  losses = tLosses;
  totalPoints = tTotal;
}

string ballTeam::getName() const
{
  return name;
}

int ballTeam::getWins() const
{
  return wins;
}

int ballTeam::getLosses() const
{
  return losses;
}

int ballTeam::getTotal() const
{
 return totalPoints;
}

bool ballTeam::operator==(const ballTeam &team)
{
  float ratio;
  float teamRatio;
  ratio = (wins/ (float)(wins + losses));
  teamRatio = (team.wins/ (float)(team.wins + team.losses));
  
  return (ratio == teamRatio);
}

bool ballTeam::operator>(const ballTeam &team)
{
  float ratio;
  float teamRatio;
  ratio = (wins/ (float)(wins + losses));
  teamRatio = (team.wins/ (float)(team.wins + team.losses));
  
  return(ratio > teamRatio);
}

bool ballTeam::operator<(const ballTeam &team)
{
  float ratio;
  float teamRatio;
  ratio = (wins/ (float)(wins + losses));
  teamRatio = (team.wins/ (float)(team.wins + team.losses));
  
  return (ratio < teamRatio);
}

istream & operator>>(istream & in, ballTeam &team)
{
  in>>team.name>>team.wins>>team.losses>>team.totalPoints;
  
  return in;
}

Driver cpp

#include <iostream>
#include <fstream>
#include "arrayListTypeT.h"
#include "ballTeam.h"
using namespace std;


int main()
{
  arrayListTypeT<ballTeam> teamList(10);
  ballTeam team;
  fstream fin;
  
  fin.open("teamStats.data");
  
  if(!fin.is_open())
    cout<<"Error: File does not exist or error opening file\n"<<endl;
  
  while(!fin.eof())
  {
    fin>>team;
    teamList.insert(team);
    
    
  }
   
  
  fin.close();
  
  return 0;
}

Recommended Answers

All 3 Replies

...
I knew something about the definitions have to be in the same file as the class prototype, the thing is the the templateclass.cpp and templateclass.h were given to use and the only code we can add is the insert function, those two files must stay seperate according to him

Close this topic. I was told by my professor that g++ cant not handle the seperate compilation.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.