Hey folks,

I am working on a project (its a continuation of my previous project)... but with a few additions. First off, i have to use class templates... I have used them before, but not when working with multiple class definitions and multiple files.

Below i will post sections of my Person.h, and Person.cpp files. I am getting linker errors with all of my functions when trying to edit them to work with templates. I am sure i am missing something rather obvious...

Person.h

#define PERSON_H

#include "340.h"

template <class T>
class Person;

template <class T>
class Person {
	public:
      Person();
      virtual ~Person();
      void setFirstName(T &x);
      T getFirstName() const;
      void setLastName(T &x);
      T getLastName() const;
      void setSSN(T &x);
      T getSSN() const;
      void setDOB(T &x);
      T getDOB() const;
      void setGender(T &x);
      T getGender() const;
      
    private:
      string firstName;
      string lastName;
      string SSN;
      string DOB;
      string gender;
};

#endif //PERSON_H

Person.cpp

#include "Person.h"

/****************************************************************
   FUNCTION:   Person()
   ARGUMENTS:  none
   RETURNS:    none
   NOTES:      this is the Person() constructor
****************************************************************/
template <class T>
Person<T>::Person()
{
}

/****************************************************************
   FUNCTION:   ~Person()
   ARGUMENTS:  none
   RETURNS:    none
   NOTES:      this is the Person destructor
****************************************************************/  
template <class T>  
Person<T>::~Person()
{
}

/****************************************************************
   FUNCTION:   setFirstName(const string &x)
   ARGUMENTS:  const string &x - the first name of student
   RETURNS:    none
   NOTES:      this function sets the students first name
****************************************************************/
template <class T>
void Person<T>::setFirstName(T &x)
{
     firstName = x;
}

/****************************************************************
   FUNCTION:   getFirstname() const
   ARGUMENTS:  none
   RETURNS:    string firstName
   NOTES:      this function returns the students first name
****************************************************************/
template <class T>
T Person<T>::getFirstName() const 
{
     return firstName;
}
...//more functions, but lots of space used... you could comment out the functions methods in the class definition if you wanted to try compiling?!

I hope someone sees an obvious mistake i am overlooking. My textbooks and previous projects all seem to be similar to what i have done on this...yet they seemed to work!

Thanks again folks

[Linker error] undefined reference to `Person::setFirstName(std::string&)'
[Linker error] undefined reference to `Person::setLastName(std::string&)'
[Linker error] undefined reference to `Person::setSSN(std::string&)'
... and the same for each function listed in the class...

So not really an 'error' but a linker error...thanks!!!

***EDIT***

I just edited my variables in the class definition to be of type T...

private:
      T firstName;
      T lastName;
      T SSN;
      T DOB;
      T gender;

Thinking that might be it...but no go there... is it something else? Cheers for helping all.

That looks like an error in getting an appropiate type built.
That can occur when you have multiple files. (compile+compiler flag dependent)

Add a template instanciation template class person<std::string>; at the end of person.cpp and if we are lucky it will fix/change the problem.

Note: If that is the problem, then expect a lot of compiler errors in person since you will not have actually compiled any instance of person yet.

StuXYZ --- thank you for your effort, i tried you above mentioned idea, and that did not work! (thank you for trying/helping though!) Soooo....

I am going to upload all files of my code. I realize thats a pain in the so and so... but for people to see exactly what im doing and how i am getting errors, it might help seeing all appropriate files for your own tests/compiling.

Thanks for your patience and time.

***EDIT****

After editing my student.h and student.cpp files... to use templates... i get ONE error...so i might be getting somewhere. I think you were right to mention that the error could be caused by using multiple files/templates.

So here is my new error:

23 C:\Users\Tony\Documents\Spring 2009\CSCI 340\Project 2\Student.h expected class-name before '{' token

On this line:

template <class T>
class Student : public Person {
	public:

I will re-upload my Student.h and Student.cpp so that changes can be seen etc.

Thanks a ton.

Attachments
#ifndef H_340
#define H_340

#include <iostream>
#include <fstream>
#include <iomanip>
#include <sstream>

#include <cstdlib>
#include <climits>
#include <cmath>
#include <ctime>

#include <algorithm>
#include <functional>
#include <iterator>
#include <string>
#include <vector>
#include <list>
#include <stack>
#include <queue>
#include <map>
#include <set>

#include <stdexcept>
using namespace std;
#endif
#include "courseInfo.h"

/****************************************************************
   FUNCTION:   courseInfo()
   ARGUMENTS:  none
   RETURNS:    none
   NOTES:      this is the constructor for the CourseInfo class
****************************************************************/
CourseInfo::CourseInfo()
{
   count = 0;
}

/****************************************************************
   FUNCTION:   ~CourseInfo()
   ARGUMENTS:  none
   RETURNS:    none
   NOTES:      this is the destructor for the CourseInfo class
****************************************************************/
CourseInfo::~CourseInfo()
{
}

/****************************************************************
   FUNCTION:   getCourseID() const
   ARGUMENTS:  none
   RETURNS:    string courseID
   NOTES:      this function returns the courseID for the student
****************************************************************/
string CourseInfo::getCourseID() const
{
	return courseID;
}

/****************************************************************
   FUNCTION:   setCourseID(const string &x)
   ARGUMENTS:  const string &x
   RETURNS:    none
   NOTES:      this function sets the courseID for the student
****************************************************************/
void CourseInfo::setCourseID(string &x)
{
	courseID = x;
}

/****************************************************************
   FUNCTION:   setYearTaken(const string &x)
   ARGUMENTS:  const string &x - the new YearTaken
   RETURNS:    none
   NOTES:      this function sets the students YearTaken for a course
****************************************************************/
void CourseInfo::setYearTaken(string &x)
{
	yearTaken = x;
}

/****************************************************************
   FUNCTION:   getYearTaken() const
   ARGUMENTS:  none
   RETURNS:    string yearTaken
   NOTES:      this returns the students YearTaken for a certain class
****************************************************************/
string CourseInfo::getYearTaken() const
{
	return yearTaken;
}

/****************************************************************
   FUNCTION:   setSemesterTaken(const string &x)
   ARGUMENTS:  const string &x - the semesterTaken value
   RETURNS:    none
   NOTES:      this function sets the students semester taken for
               a specific course
****************************************************************/
void CourseInfo::setSemesterTaken(string &x)
{
	semesterTaken = x;
}

/****************************************************************
   FUNCTION:   getSemesterTaken() const
   ARGUMENTS:  none
   RETURNS:    string semesterTaken - returns the semester taken
   NOTES:      this function gets the students semester taken
****************************************************************/
string CourseInfo::getSemesterTaken() const
{
	return semesterTaken;
}

/****************************************************************
   FUNCTION:   setGrade(const string &x)
   ARGUMENTS:  const string &x
   RETURNS:    none
   NOTES:      this functions sets the grade for a certain class
****************************************************************/     
void CourseInfo::setGrade(string &x)
{
	grade = x;
}
      
/****************************************************************
   FUNCTION:   getGrade() const
   ARGUMENTS:  none
   RETURNS:    string grade
   NOTES:      this function returns the grade of the student in 
                a specific class
****************************************************************/
string CourseInfo::getGrade() const
{
	return grade;
}

/****************************************************************
   FUNCTION:   incrementCount(int &x)
   ARGUMENTS:  int x - the value of count
   RETURNS:    none
   NOTES:      this function increments the number of courses input
****************************************************************/
void CourseInfo::incrementCount(int &x)
{
	x = x + 1;
}

/****************************************************************
   FUNCTION:   getCoount() const
   ARGUMENTS:  none
   RETURNS:    int count
   NOTES:      this function returns the count of classes
****************************************************************/
int CourseInfo::getCount() const
{
	return count;
}
/****************************************************************
   FILE:      courseInfo.h
   AUTHOR:    Anthony Hogan
   LOGON ID:  Z109079
   DUE DATE:  1/23/2009

   PURPOSE:   Includes the class courseInfo information / prototypes 
****************************************************************/
#ifndef COURSEINFO_H
#define COURSEINFO_H

#include "340.h"

class CourseInfo {
	public:
      CourseInfo();
      virtual ~CourseInfo();
      void setCourseID(string &x);
      string getCourseID() const;
      void setYearTaken(string &x);
      string getYearTaken() const;
      void setSemesterTaken(string &x);
      string getSemesterTaken() const;
      void setGrade(string &x);
      string getGrade() const;
      void incrementCount(int &x);
      int getCount() const;
      
    private:
      string courseID;
      string yearTaken;
      string semesterTaken;
      string grade;
      int count;
      
};


#endif //COURSEINFO_H
/****************************************************************
   PROGRAM:   Project 1
   AUTHOR:    Anthony Hogan
   LOGON ID:  Z109079
   DUE DATE:  1/26/2009

   FUNCTION:  creates a program that enables a user to input
   		    student data. Including name, zid, SSN, and courses.

   INPUT:     from keyboard

   OUTPUT:    A list of all courses taken/schedules for a certain
   			  student.

   NOTES:     Uses 6 files. Student.h, Student.cpp, Person.h, Person.cpp,
   			  courseInfo.h, courseInfo.cpp, and 340.h.
****************************************************************/
#include "Person.h"
#include "Student.h"
#include "courseInfo.h"
#include "Node.h"
#include "340.h"

int main()
{
   int choice = 0;       
	    
   Student NIU_Student; //creates a student object
   while (choice != 999)
   {
         cout << "\nStudent Registration Database" << endl;
         cout << "Please choose from the options below (type 999 to quit)\n" << endl;
         cout << "1. Enter new student information" << endl;
         cout << "2. Enter new class information for student" << endl;
         cout << "3. Edit student information (not valid)" << endl;
         cout << "4. Edit class information for student (not valid)" << endl;
         cout << "5. Print student information\n" << endl;
         cout << "Please enter your choice: (the press enter, 999 to quit)";
         cin >> choice;
         
   switch(choice)
   {
   case 1:
        {
	       string x;
	       cout << "Please enter the first name: ";
	       cin >> x;
	       NIU_Student.setFirstName(x);
	       cout << "Please enter the last name: ";
	       cin >> x;
	       NIU_Student.setLastName(x);
	       cout << "Please enter students social security number: ";
	       cin >> x;
	       NIU_Student.setSSN(x);
	       cout << "Please enter student DoB: ";
	       cin >> x;
	       NIU_Student.setDOB(x);
	       cout << "Please enter the student's gender: ";
	       cin >> x; 
           NIU_Student.setGender(x);
           cout << "Please enter students ZID: ";
           cin >> x;
           NIU_Student.setZID(x);
           break;
         }
    case 2:
         { 
           string entry, 
                  more;
           do
           {        
             cout << "Please enter course name: ";
             cin >> entry;
             NIU_Student.courses[NIU_Student.getCount()].setCourseID(entry);
             cout << "Please enter year taken: ";
             cin >> entry;
             NIU_Student.courses[NIU_Student.getCount()].setYearTaken(entry);
             cout << "Please enter semester taken: ";
             cin >> entry;
             NIU_Student.courses[NIU_Student.getCount()].setSemesterTaken(entry);
             cout << "Please enter grade for course: ";
             cin >> entry;
             NIU_Student.courses[NIU_Student.getCount()].setGrade(entry);
            cout << "Enter another class? (Y/N): ";
            cin >> more;
            NIU_Student.incrementCount();
           } while (more == "Y" || more == "y");
           break;
         }
    case 3:
         {
           cout << "Choice entered was 3" << endl;
           break;
         }
    case 4:
         {
           cout << "Choice entered was 4" << endl;
           break;
         }
    case 5:
         {
		   NIU_Student.infoPrint();
         break;
         }  
    case 999:
         {
           cout << "Quitting..." << endl;
           break;
         }
    } // end of switch statement
    } // end of while
    
    return 0;
}
//empty file
/****************************************************************
   FILE:      Node.h
   AUTHOR:    Anthony Hogan
   LOGON ID:  Z109079
   DUE DATE:  2/6/2009

   PURPOSE:  Includes the Node declaration 
****************************************************************/
#ifndef NODE_H
#define NODE_H

#include "340.h"

template <class T>
class Node {
	public:
     Node(); //constructor
     //Node(****); // 2nd constructor for passing in value
     ~Node(); //destructor 
     T info;
     Node * next;  
};

#endif // ENDIF NODE_H
#include "Person.h"

/****************************************************************
   FUNCTION:   Person()
   ARGUMENTS:  none
   RETURNS:    none
   NOTES:      this is the Person() constructor
****************************************************************/
template <class T>
Person<T>::Person()
{
}

/****************************************************************
   FUNCTION:   ~Person()
   ARGUMENTS:  none
   RETURNS:    none
   NOTES:      this is the Person destructor
****************************************************************/  
template <class T>  
Person<T>::~Person()
{
}

/****************************************************************
   FUNCTION:   setFirstName(const string &x)
   ARGUMENTS:  const string &x - the first name of student
   RETURNS:    none
   NOTES:      this function sets the students first name
****************************************************************/
template <class T>
void Person<T>::setFirstName(T &x)
{
     firstName = x;
}

/****************************************************************
   FUNCTION:   getFirstname() const
   ARGUMENTS:  none
   RETURNS:    string firstName
   NOTES:      this function returns the students first name
****************************************************************/
template <class T>
T Person<T>::getFirstName() const 
{
     return firstName;
}

/****************************************************************
   FUNCTION:   setLastName(const string &x)
   ARGUMENTS:  const string &x - the students last name
   RETURNS:    none
   NOTES:      this function sets the students last name
****************************************************************/
template <class T>
void Person<T>::setLastName(T &x) 
{
     lastName = x;
}

/****************************************************************
   FUNCTION:   getLastName() const
   ARGUMENTS:  none
   RETURNS:    string lastName
   NOTES:      this function returns the students last name
****************************************************************/
template <class T>
T Person<T>::getLastName() const 
{
     return lastName;
}

/****************************************************************
   FUNCTION:   setSSN(const string &x)
   ARGUMENTS:  const string &x
   RETURNS:    none
   NOTES:      this function sets the students SSN
****************************************************************/
template <class T>
void Person<T>::setSSN(T &x) 
{
     SSN = x;
}

/****************************************************************
   FUNCTION:   getSSN() const
   ARGUMENTS:  none
   RETURNS:    string SSN
   NOTES:      this function returns the students SSN
****************************************************************/
template <class T>
T Person<T>::getSSN() const 
{
       return SSN;
}

/****************************************************************
   FUNCTION:   setDOB(const string &x)
   ARGUMENTS:  const string &x - the students DOB
   RETURNS:    none
   NOTES:      this function sets the students DOB
****************************************************************/
template <class T>
void Person<T>::setDOB(T &x) 
{
     DOB = x;
}

/****************************************************************
   FUNCTION:   getDOB() const
   ARGUMENTS:  none
   RETURNS:    string DOB
   NOTES:      this function returns the students DOB
****************************************************************/
template <class T>
T Person<T>::getDOB() const 
{
       return DOB;
}

/****************************************************************
   FUNCTION:   setGender(const string &x)
   ARGUMENTS:  const string &x - the students gender
   RETURNS:    none
   NOTES:      this function sets the student gender
****************************************************************/
template <class T>
void Person<T>::setGender(T &x) 
{
     gender = x;
}

/****************************************************************
   FUNCTION:   getGender() const
   ARGUMENTS:  none
   RETURNS:    string gender 
   NOTES:      this function returns the students gender
****************************************************************/
template <class T>
T Person<T>::getGender() const 
{
       return gender;
}
/****************************************************************
   FILE:      Person.h
   AUTHOR:    Anthony Hogan
   LOGON ID:  Z109079
   DUE DATE:  1/23/2009

   PURPOSE:   Includes the class Person information / prototypes 
****************************************************************/
#ifndef PERSON_H
#define PERSON_H

#include "340.h"

template <class T>
class Person;

template <class T>
class Person {
	public:
      Person();
      virtual ~Person();
      void setFirstName(T &x);
      T getFirstName() const;
      void setLastName(T &x);
      T getLastName() const;
      void setSSN(T &x);
      T getSSN() const;
      void setDOB(T &x);
      T getDOB() const;
      void setGender(T &x);
      T getGender() const;
      
    private:
      T firstName;
      T lastName;
      T SSN;
      T DOB;
      T gender;
};

#endif //PERSON_H
#include "Student.h"


/****************************************************************
   FUNCTION:   Student()
   ARGUMENTS:  none
   RETURNS:    none
   NOTES:      this is the Student class constructor
****************************************************************/
template <class T>
Student<T>::Student()
{
	count = 0;
}

/****************************************************************
   FUNCTION:   ~Student()
   ARGUMENTS:  none
   RETURNS:    none
   NOTES:      this is the destructor for the Student class
****************************************************************/   
template <class T>
Student<T>::~Student()
{
}

/****************************************************************
   FUNCTION:   incrementCount()
   ARGUMENTS:  none
   RETURNS:    none
   NOTES:      This function increments count so that the number
               of classes added are counted on entry
****************************************************************/
template <class T>
void Student<T>::incrementCount()
{
	count = count + 1;
}

/****************************************************************
   FUNCTION:   getZID()
   ARGUMENTS:  none
   RETURNS:    ZID - returns the students ZID number
   NOTES:      This function simply returns the students ZID#
****************************************************************/
template <class T>
T Student<T>::getZID() const
{
     return ZID;
}

/****************************************************************
   FUNCTION:   setZID(const string &x)
   ARGUMENTS:  string x
   RETURNS:    none
   NOTES:      this function sets the students ZID with the value
               passed to it.
****************************************************************/
template <class T>
void Student<T>::setZID(T &x)
{
     ZID = x;
}

/****************************************************************
   FUNCTION:   getCount() const
   ARGUMENTS:  none
   RETURNS:    int count
   NOTES:      this function returns the count of the number of 
               classes added to the students registration etc
****************************************************************/
template <class T>
int Student<T>::getCount() const
{
	return count;
}

/****************************************************************
   FUNCTION:   infoPrint()
   ARGUMENTS:  none
   RETURNS:    none
   NOTES:      this prints the students information, including the
               basic information, aswell as class information
****************************************************************/
template <class T>
void Student<T>::infoPrint()
{	
  cout << Person<T>::getFirstName()<< " " << Person<T>::getLastName()
       << " " << Person<T>::getSSN() << " " << Person<T>::getDOB()
       << " " << Person<T>::getGender()<< " " << getZID()
       << endl;      
     
	int count = 0;          
	while (count <= getCount())
           {
             cout << setw(8) << courses[count].getCourseID() << " " 
                << setw(5) << courses[count].getYearTaken() << " " 
                << setw(7) << courses[count].getSemesterTaken() << " " 
                << setw(3) << courses[count].getGrade() << endl;
             count++;
           }
}
/****************************************************************
   FILE:      Student.h
   AUTHOR:    Anthony Hogan
   LOGON ID:  Z109079
   DUE DATE:  1/23/2009

   PURPOSE:   Includes the class Student information / prototypes 
****************************************************************/
#ifndef STUDENT_H
#define STUDENT_H

#include "Person.h"
#include "courseInfo.h"
#include "340.h"

template <class T>
class Person;

template <class T>
class Student;

template <class T>
class Student : public Person {
	public:
      Student();
      virtual ~Student(); 
      T getZID() const;
      void setZID(T &x);    
      CourseInfo courses[10];
      void incrementCount();
      int getCount() const;
      void infoPrint(); 
      
    private:
      T ZID;
      int count;
       
};

#endif //STUDENT_H

You have some errors: ALL of which should have been explained by you compiler, that you can get to linking is just telling you to get a better compiler (gcc is the minimum and free.).
(a) to (c) stop your code compiling/linking.

(a) student inherrits from Person BUT person is a template class so
which person is student inherriting from e.g. Person<int> Person<std::string> ????

(b) Put the line given in my last post at the bottom of Person.cpp

(c) You cant use Person:: in print_info (student) , so get rid of it, just getFirstName() etc.
[well you can use Person<std::string> or whatever you decided on Student to inherrit from,
but that will give you an unnecessary dependence on your template choise.]

(d) Fixed size array of courseInfo looks bad.

(e) return const references for strings in the getGrade() etc.

(f) void CourseInfo::incrementCount(int &x) {x = x + 1;} This HAS to be wrong!! (I did lol at this!)

(g) Grade/year as strings???

(h) Add some checking etc.

Those threefixes (a-c) get it to compile and link.

Adding your functionallity is another story.

This article has been dead for over six months. Start a new discussion instead.