可能重复:
未定义的引用
我已经对这一组错误消息猛烈抨击了大约 4 个小时,但我似乎无法弄清楚。我以前没有在这里发帖,所以如果它不在正确的区域或者我做错了什么,我提前道歉。无论如何,我收到的错误消息是:
main.cpp|28|undefined reference to `LinkedSortedList<Employee>::LinkedSortedList()'|
main.cpp|52|undefined reference to `empPrint(LinkedSortedList<Employee>&)'|
main.cpp|58|undefined reference to `empSave(LinkedSortedList<Employee>&, std::string)'|
main.cpp|65|undefined reference to `empLoad(LinkedSortedList<Employee>&, std::string)'|
main.cpp|70|undefined reference to `LinkedSortedList<Employee>::~LinkedSortedList()'|
main.cpp|70|undefined reference to `LinkedSortedList<Employee>::~LinkedSortedList()'|
obj\Debug\main.o||In function `Z9empSearchR16LinkedSortedListI8EmployeeE':|
main.cpp|109|undefined reference to `LinkedSortedList<Employee>::getHead()'|
我的 main.cpp 如下:
#include <iostream>
#include <string>
#include <stdio.h>
#include <fstream>
#include "SortedList.h"
#include "LinkedSortedList.h"
#include "Employee.h"
#include "LinkedNode.h"
using namespace std;
void newEmp(LinkedSortedList <Employee>& empList);
void empSearch(LinkedSortedList <Employee>& empList);
void empPrint(LinkedSortedList <Employee>& empList);
void empSave(LinkedSortedList <Employee>& empList, string file);
void empLoad(LinkedSortedList <Employee>& empList, string file);
int main()
{
//int empID;
bool menuFinish = false;
LinkedSortedList<Employee> empList;
char selection;
while (!menuFinish)
//simple menu system through cout, the selection is read in through cin
//and converted to upper case for simplicity during the conditionals
cout << "Menu" << endl;
cout << "(I)nsert new record" << endl;
cout << "(E)mployee ID search" << endl;
cout << "(P)rint employee info" << endl;
cout << "(S)ave database to a file" << endl;
cout << "(L)oad database from file" << endl;
cout << "(Q)uit" << endl;
cout << "Enter selection " << endl;
cin >> selection;
selection = toupper(selection);
//menu selections are compared with their functions
if (selection == 'I')
newEmp(empList);
else if (selection == 'E')
empSearch(empList);
else if (selection == 'P')
empPrint(empList);
else if (selection == 'S')
{
string fileName;
cout << "Enter a filename to save the database to " << endl;
cin >> fileName;
empSave(empList, fileName);
}
else if (selection == 'L')
{
string fileName;
cout << "Enter the filename to load the database from " << endl;
cin >> fileName;
empLoad(empList, fileName);
}
else if (selection == 'Q')
menuFinish = true;
else
cout << "Incorrect choice " << endl;
}
//function creates a new employee
void newEmp(LinkedSortedList <Employee>& empList)
{
string firstName;
string lastName;
int empID = -1;
cout << "Please enter the first name " << endl;
cin >> firstName;
cout << "Please enter the last name " << endl;
cin >> lastName;
while (empID > 9999999 || empID < 0)
{
cout <<"Please enter the employee ID " << endl;
cin >> empID;
}
//puts the employee in the db unless they're already found, then outputs an
//error on the screen
Employee emp(firstName, lastName, empID);
bool findEmp = empList.find(emp);
if (!findEmp)
empList.insert(emp);
else
cout << "Emlpoyee ID " << empID << " already in use " << endl;
}
//function to search for an employee based on their employee ID
void empSearch (LinkedSortedList <Employee>& empList)
{
int empID;
int sizeOfList = 0;
bool noEmp = true;
cout << "Enter employee ID " << endl;
cin >> empID;
LinkedNode <Employee>* temp = empList.getHead();
while (sizeOfList < empList.size() && noEmp)
{
sizeOfList++;
if (empID == temp->value.getEmpID())
{
cout << "Searched " << sizeOfList << "employees " << endl;
cout << "Found record: " << temp->value;
noEmp = false;
}
temp = temp->next;
}
if (noEmp)
cout << "Search of " << sizeOfList << " employees. Employee not found" << endl;
}
//function used to print the first and last five employees from the db
void empPrint (LinkedSortedList <Employee>& empList)
{
if (empList.size() <= 10)
{
empList.print();
}
else
{
LinkedNode<Employee>* temp = empList.getHead();
cout << "First five employees: " << endl;
for (int i = 0; i < 5; i++)
{
cout << temp->value << endl;
i++;
temp = temp->next;
}
int midList = empList.size()-5;
for (int i = 0; i < midList; i++)
{
temp = temp->next;
}
cout << "Last five employees: " << endl;
for (int i = 0; i < 5; i++)
{
cout << temp->value << endl;
i++;
temp = temp->next;
}
}
}
//function used to save the employee information from the db to a file
void empSave(LinkedSortedList<Employee>& empList, string fileName)
{
string lastName;
string firstName;
//int empID;
ofstream output;
output.open(fileName.c_str());
if (!output)
{
cout << "File not saved" << endl;
}
else
{
LinkedNode<Employee>* temp = empList.getHead();
int i = 0;
while (i < empList.size())
{
output << temp->value.getLastName() << " " << temp->value.getFirstName() << " " << temp->value.getEmpID() << endl;
i++;
temp = temp->next;
}
}
output.close();
}
//function used to load the employee information from a file to the db
void empLoad(LinkedSortedList<Employee>& empList, string fileName)
{
if (empList.size() > 0)
{
empList.clear();
}
ifstream input;
input.open(fileName.c_str());
if (!input)
{
cout << "No file exists" << endl;
}
else
{
int empID;
string firstName;
string lastName;
string delimiter;
while(input.good());
{
getline(input, delimiter, '\n');
getline(input, lastName, ' ');
getline(input, firstName, ' ');
input >> empID;
Employee emp(lastName, firstName, empID);
bool empFound = empList.find(emp);
if(!empFound)
{
empList.insert(emp);
}
else
cout << "Employee already exists" << endl;
}
}
}
我的 LinkedSortList.cpp 是:
#ifndef _LinkedSortedList_
#define _LinkedSortedList_
#include "Employee.h"
#include "LinkedSortedList.h"
#include "SortedList.h"
#include "LinkedNode.h"
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
//default constructor
//sets head to null and makes the size of the list 0
template <class Elem>
LinkedSortedList<Elem>::LinkedSortedList()
{
head = NULL;
listSize = 0;
}
//destructor, clears list THEN deletes the head so memory leaks are
//stopped
template <class Elem>
LinkedSortedList<Elem>::~LinkedSortedList()
{
clear();
delete head;
}
//clears the list, freeing memory and stopping leaks and resets the
//list size
template <class Elem>
void LinkedSortedList<Elem>::clear()
{
LinkedNode<Elem> *indexPtr = head;
while (head != NULL)
{
head = head->next;
delete indexPtr;
indexPtr = head;
}
listSize = 0;
}
//finds a search value in the list... if it finds it then it returns true,
//otherwise it returns false
template <class Elem>
bool LinkedSortedList<Elem>::find(Elem searchValue) const
{
LinkedNode<Elem>* indexPtr = head;
while (indexPtr != NULL)
{
if (indexPtr->value == searchValue)
{
return true;
}
indexPtr = indexPtr->next;
}
return false;
}
//gets and DELETES first value in the list - if it finds nothing then
//return false, otherwise true
template <class Elem>
bool LinkedSortedList<Elem>::getFirst(Elem &returnValue)
{
LinkedNode<Elem>* indexPtr = head;
if (indexPtr == NULL)
return false;
else
{
head = head->next;
returnValue = indexPtr->value;
delete indexPtr;
listSize--;
return true;
}
returnValue = indexPtr->value;
}
//prints the list to cout or prints a warning if the list contains
//no values
template <class Elem>
void LinkedSortedList<Elem>::print() const
{
if (head == NULL)
{
cout << "No elements in the list" << endl;
}
else
{
LinkedNode<Elem>* indexPtr = head;
while (indexPtr != NULL)
{
cout << indexPtr->value << endl;
indexPtr = indexPtr->next;
}
}
}
//returns the size of the list to the caller
template <class Elem>
int LinkedSortedList<Elem>::size() const
{
return listSize;
}
//inserts a value into the list where it should go, if the list is empty it will
//say there are no existing nodes
template <class Elem>
bool LinkedSortedList<Elem>::insert(Elem newValue)
{
LinkedNode<Elem>* indexPtr = head;
LinkedNode<Elem>* newNode;
//newNode->value = newValue;
try
{
newNode = new LinkedNode<Elem>(newValue);
}
catch(exception e)
{
cout<<"Exception reached: " << e.what() << endl;
return false;
}
//checks to see if the list is empty, if it is then it makes the newNode
//the head
if (head == NULL)
{
cout << "No existing nodes" << endl;
head = newNode;
cout << "First node is now " << head->value << endl;
listSize++;
return true;
}
/*looks to see if the value of the newNode is less than or equal to the
index, if it is then it sets the point of the newNode equal to the head
then makes the head the newNode and increments the listSize by one to keep
track of the size of the list and returns true*/
else if (newNode->value <= head->value)
{
newNode->next = head;
head = newNode;
listSize++;
return true;
}
/*if the newNode value is greater than the index, then:*/
else
{
while(indexPtr->next != NULL && newNode->value > indexPtr->next->value)
{
indexPtr = indexPtr->next;
}
if (indexPtr->next == NULL)
{
indexPtr->next = newNode;
listSize++;
return true;
}
else
{
newNode->next = indexPtr->next;
indexPtr->next = newNode;
listSize++;
return true;
}
}
}
//added for project 2 to return the head of the LL
template <class Elem>
LinkedNode<Elem>* LinkedSortedList<Elem>::getHead()
{
return head;
}
#endif
Employee.cpp 是:
#ifndef _Employee_
#define _Employee_
#include "Employee.h"
#include "LinkedSortedList.h"
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
//blank default constructor
Employee::Employee()
{
}
//constructor that takes 3 parameters and sets them
Employee::Employee(string lastName, string firstName, int eID)
{
this->lastName = lastName;
this->firstName = firstName;
this->empID = eID;
}
//blank deconstructor
Employee::~Employee()
{
}
//overloaded equality operator
bool Employee::operator==(Employee &nextEmployee)
{
if (this->empID == nextEmployee.empID)
return true;
else
return false;
}
//overloaded less than or equal to operator
bool Employee::operator <= (Employee &nextEmployee)
{
if (this->empID <= nextEmployee.empID)
return true;
else
return false;
}
//overloaded greater than or equal to operator
bool Employee::operator >= (Employee &nextEmployee)
{
if (this->empID >= nextEmployee.empID)
return true;
else
return false;
}
//overloaded less than operator
bool Employee::operator < (Employee &nextEmployee)
{
if (this->empID < nextEmployee.empID)
return true;
else
return false;
}
//overloaded greater than operator
bool Employee::operator > (Employee &nextEmployee)
{
if (this->empID > nextEmployee.empID)
return true;
else
return false;
}
// overloaded output stream operator
ostream& operator<<(ostream& os, const Employee empl)
{
os << "Last: " << empl.lastName << endl;
os << "First: " << empl.firstName << endl;
os << "Employee ID: " << empl.empID << endl;
return os;
}
#endif
我的头文件 LinkedSortedList.h:
#ifndef _LinkedSortedListClass_
#define _LinkedSortedListClass_
#include "SortedList.h"
#include "LinkedNode.h"
#include <iostream>
#include <fstream>
#include <string>
//using namespace std;
template <class Elem>
class LinkedSortedList : public SortedList< Elem >
{
public:
LinkedSortedList();
~LinkedSortedList();
virtual void clear();
virtual bool insert(Elem newValue);
virtual bool getFirst(Elem &returnValue);
virtual void print() const;
virtual bool find(Elem searchValue) const;
virtual int size() const;
LinkedNode<Elem>* getHead(); //added for project 2
private:
LinkedNode<Elem>* head;
int listSize;
};
#endif
最后(哇!)我的 Employee.h 在这里:
#ifndef _EmployeeClass_
#define _EmployeeClass_
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
class Employee
{
public:
Employee();
~Employee();
Employee(string, string, int);
bool operator == (Employee& nextEmployee);
bool operator <= (Employee &nextEmployee);
bool operator >= (Employee &nextEmployee);
bool operator < (Employee &nextEmployee);
bool operator > (Employee &nextEmployee);
friend ostream& operator<<(ostream& os, const Employee empl);
string getLastName(){return lastName;}
string getFirstName(){return firstName;}
int getEmpID(){return empID;}
private:
string lastName;
string firstName;
int empID;
};
#endif
我只是没有看到这里的问题,我已经和我的助教、帮助室工作人员和其他学生谈过了。我还没有收到教授的回复,但我怀疑这个周末我会不会收到她的来信。非常感谢您提供的任何见解。我需要一些泰诺。-乔什