Undefined Reference To Class::Function()

I don't know what I'm doing wrong. I've checked the includes and my makefile and everything seems fine... I can't find what I'm missing though. It could also have something to do with the Inheritence/Polymorphism since I've never done that before.

There's not enough space to copy all the relevant code over, so below I just have my error messages, makefile, main, and all the includes from the various files. I don't know what else to include so let me know and I can put it in the replies.

Error Messages:
g++ -std=c++11 main.o getNum.o Menu.o randNum.o Building.o Person.o Student.o Instructor.o University.o -o output
main.o: In function `main':
main.cpp:(.text+0x2c): undefined reference to `Building::Building()'
main.cpp:(.text+0x4a): undefined reference to `Student::Student()'
main.cpp:(.text+0x59): undefined reference to `Instructor::Instructor()'
main.o: In function `Person::Person()':
main.cpp:(.text._ZN6PersonC2Ev[_ZN6PersonC5Ev]+0x13): undefined reference to `vtable for Person'
main.o: In function `Person::~Person()':
main.cpp:(.text._ZN6PersonD2Ev[_ZN6PersonD5Ev]+0x13): undefined reference to `vtable for Person'
main.o:(.rodata._ZTV10Instructor[_ZTV10Instructor]+0x10): undefined reference to `Person::do_work()'
main.o:(.rodata._ZTV10Instructor[_ZTV10Instructor]+0x18): undefined reference to `Person::infoPrint()'
main.o:(.rodata._ZTV7Student[_ZTV7Student]+0x10): undefined reference to `Person::do_work()'
main.o:(.rodata._ZTV7Student[_ZTV7Student]+0x18): undefined reference to `Person::infoPrint()'
main.o:(.rodata._ZTI10Instructor[_ZTI10Instructor]+0x10): undefined reference to `typeinfo for Person'
main.o:(.rodata._ZTI7Student[_ZTI7Student]+0x10): undefined reference to `typeinfo for Person'
collect2: error: ld returned 1 exit status
make: *** [output] Error 1

MAKEFILE:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
  output: main.o getNum.o Menu.o randNum.o Building.o Person.o Student.o Instructor.o University.o
	g++ -std=c++11 main.o getNum.o Menu.o randNum.o Building.o Person.o Student.o Instructor.o University.o -o output

main.o: main.cpp
	g++ -c main.cpp

getNum.o: getNum.cpp getNum.hpp
	g++ -c getNum.cpp

Menu.o: Menu.cpp Menu.hpp
	g++ -c Menu.cpp

randNum.o: randNum.cpp randNum.hpp
	g++ -c randNum.cpp

University.o: University.cpp University.hpp
	g++ -std=c++11 -c University.cpp

Building.o: Building.cpp Building.hpp
	g++ -c Building.cpp

Person.o: Person.cpp Person.hpp
	g++ -c Person.cpp

Student.o: Student.cpp Student.hpp
	g++ -c Student.cpp

Instructor.o: Instructor.cpp Instructor.hpp
	g++ -c Instructor.cpp

make clean: 
	rm *.o output


MAIN
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
#include "University.hpp"
#include "Building.hpp"
#include "Person.hpp"
#include "Student.hpp"
#include "Instructor.hpp"
#include "getNum.hpp"
#include "Menu.hpp"
#include "randNum.hpp"
#include <iostream>
#include <string>

int main()
{
	Menu menu;
	University university;
	Building building;
	Person person;
	Student student;
	Instructor instructor;
	int choice;

	// manually instantiate buildings and people
	Building* b1 = new Building("Agricultural & Life Sciences Bldg", 185629, "2750 SW Campus Way");
	Building* b2 = new Building("Dixon Recreation Center",173776, "425 SW 26th Street");
	Person* s1 = new Student("Itsame Mario",24,3.8);
	Person* i1 = new Instructor("Lyfe Bytes", 42, 1.2);
	university.newBuilding(b1);
	university.newBuilding(b2);
	university.newPerson(s1);
	university.newPerson(i1);

	do
	{
		 choice=menu.getNum("MENU:\n   1.Print Building Info\n   2.Print People Info\n   3. Choose person to do work\n   4.Add New Building\n   5.Add New Person\n   6.Exit",1,6);

		if (choice==1) //print building info
		{
			university.printBuildings();
		}
		else if (choice==2 || choice==3) //print people & do work
		{
			university.printPeople(choice);		
		}
		else if(choice==4) //add new building
		{
			std::string names;
			menu.message("What is the name of the building?");
			std::cin >> names;
			int feet = menu.getNum("What is the sq. footage?",1,1000000);
			std::string adds;
			menu.message("What is the address?");
			std::cin >> adds;
			Building* b3 = new Building(names,feet,adds);
			university.newBuilding(b3);
		}
		else if(choice==5) //add new person
		{
			int num = menu.getNum("1-New Student\n2-New Instructor",1,2);
			if (num==1)
			{
				Person* s2 = new Student(student.setName(),student.setAge(),student.setGPA());
				university.newPerson(s2);
				
			}
			else //num==2
			{
				Person* i2 = new Instructor(instructor.setName(),instructor.setAge(),instructor.setRating());
				university.newPerson(i2);
			}
		}
		else //quits
		{
			menu.message("You've quit the program, goodbye!");
		}
 	}while(choice!=6);
	
	return 0;
}


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
//BUILDING.HPP & CPP

#ifndef BUILDING_HPP
#define BUILDING_HPP
#include <string>

// Building class declaration

class Building

{
	private:
		std::string name;
		int size;
		std::string address;	
	public:
		Building();
		Building(std::string nameIn, int sizeIn, std::string addressIn);
		void infoPrint();
};

#endif




//included inf Building.cpp
#include "Building.hpp"
#include "Menu.hpp"


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
//PERSON.HPP & PERSON.CPP
#ifndef PERSON_HPP
#define PERSON_HPP

#include <string>

// Person class declaration

class Person

{
	protected:
		std::string name;
		int age;
	public:
		Person();
		virtual ~Person();
		virtual void do_work();
		virtual void infoPrint();
		int setAge();
		std::string setName();
		
	
};
#endif

//Person.cpp
#include "Person.hpp"
#include "randNum.hpp"
#include "Menu.hpp"
#include <iostream>
#include <string>
/***************
 * setAge
 * sets the age of the person object
 * *************/

int Person::setAge()
{
	Menu menu;
	
	int choice = menu.getNum("1-Randomize Age\n2-Manual Age Entry",1,2);
	
	if (choice==1) //random
	{
		age = rangedRand(18,80);
	}
	else
	{
		age = menu.getNum("Please enter the age of this person (18-80)",18,80);	
	}
	
	return age;
}

/*****************
 * setName
 * sets name for object
 * ***************/
std::string Person::setName()
{
	Menu menu;
	std::string answer;

	menu.message("Please enter the name of this person");
	std::cin >> answer;

	name=answer;
	
	return name;

}


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
//STUDENT.HPP & STUDENT.CPP
#ifndef STUDENT_HPP
#define STUDENT_HPP
#include <string>
#include "Person.hpp"

// Student class declaration

class Student: public Person
{
	private:
		double GPA;
	public:
		Student();
		Student(std::string nameIn, int ageIn, int score);
		double setGPA();
		void do_work(); //virtual function
		void infoPrint(); //virtual function


};

#endif

//included in Student.cpp
#include "randNum.hpp"
#include "getNum.hpp"
#include "Person.hpp"
#include "Student.hpp"
#include "Menu.hpp"
#include <iostream> 


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
//INSTRUCTOR.HPP
#ifndef INSTRUCTOR_HPP
#define INSTRUCTOR_HPP
#include <string>
#include "Person.hpp"

// Instructor class declaration

class Instructor: public Person
{
	private:
		double rating;
	public:
		Instructor();
		Instructor(std::string nameIn, int ageIn, int score);
		double setRating();
		void do_work(); //virtual function
		void infoPrint(); //virtual function

};

#endif


//included in Instructor.cpp
#include "Person.hpp"
#include "Instructor.hpp"
#include "randNum.hpp"
#include "Menu.hpp"
#include "getNum.hpp"
#include <iostream> 

Last edited on
You have declared your class methods in your HPP files, but where are the method definitions in your CPP files?

Your CPP files, as posted here, just include headers, no actual code as expected.
And I forgot to include University info so here it is
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#ifndef UNIVERSITY_HPP
#define UNIVERSITY_HPP

#include "Building.hpp"
#include "Student.hpp"
#include "Instructor.hpp"
#include "Person.hpp"

#include <string>
#include <vector>

// University class declaration

class University

{
	private:
		std::string name;
		std::vector<Building*> buildings;
		std::vector<Person*> people;	
	public:
		University();
		~University();
		void newPerson(Person* p);
		void newBuilding(Building* b);
		void printBuildings();
		void printPeople(int choiceIn);


};

#endif

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
#include "University.hpp"
#include "Menu.hpp"
#include <vector>
#include <iostream>

/****************
 * University
 * Constructor that sets name to OSU's
 * ************/

University::University()
{
	name="Oregon State University";
}

/****************
 * University
 * Destructor
 * **************/
University::~University(){}

/****************
 * newPerson
 * adds person to the people vector
 * **************/
void University::newPerson(Person* p)
{
	people.push_back(p);
}

/***************
 * newBuilding
 * adds building to building vector
 * ************/
void University::newBuilding(Building* b)
{
	buildings.push_back(b);
}

/***************
 * printBuildings
 * prints out the data for the buildings in the buildings vector
 * *************/
void University::printBuildings()
{
	Menu menu;
	int count=1;
	for (Building* b : buildings)
	{
		menu.intResult("Building ",count);
		b->infoPrint();
		count++;
	}
}

/*****************
 * printPeople
 * prints out the data for the people objects stored in the people vector
 * **************/
void University::printPeople(int choiceIn)
{
	Menu menu;
	int count=1;
	for (Person* p : people)
	{
		menu.intResult("Person ",count);
		p->infoPrint();
		count++;
	}
	if (choiceIn==3)
	{
		int pick=menu.getNum("Which person would you like to do work?",1,count); 	
		people.at(pick-1)->do_work();
	}
}
Also I couldn't post them because the length exceeded the character limit for a post. But I just realized that I didn't delete any of my dynamic memory at the end. Could that be the reason why these weird errors are popping up?


EDIT: After fixing the delete issue the same error is popping up. I'll include the code in the member definitions in the replies below since It wont all fit in one post
Last edited on
Building.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include "Building.hpp"
#include "Menu.hpp"

/*******************
 * Building
 * Constructor that initializes member variables with user data
 * ****************/
Building::Building(std::string nameIn, int sizeIn, std::string addressIn)
{
	name=nameIn;
	size=sizeIn;
	address=addressIn;
}

/*******************
 * infoPrint
 * Prints out name, sq footage, and address of building
 * *****************/
void Building::infoPrint()
{
	Menu menu;
	menu.stringResult("Name: ",name);
	menu.intResult("Size: ",size);
	menu.stringResult("Address: ",address);

}

Instructor.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#include "Person.hpp"
#include "Instructor.hpp"
#include "randNum.hpp"
#include "Menu.hpp"
#include "getNum.hpp"
#include <iostream>

/****************
 *Instructor
 *constructor that updates object with user input
*****************/

Instructor::Instructor(std::string nameIn, int ageIn, int score)
{
	name=nameIn;
	age=ageIn;
	rating=score;
}
 
/**************
 * setRating
 * sets member variable rating
 * ***********/

double Instructor::setRating()
{
	
	std::cout << "What is this instructor's rating (0.0 - 4.0)?";
	do
	{
		rating = getDouble();
		if (rating<0.0 || rating>5.0)
		{
			std::cout << "Double selected is out of range. Please enter a double 0.0 - 4.0";
		}
	}while (rating<0.0 || rating>5.0);
}

/***************
 * do_work
 * will generate random number of hours worked, then return message saing 'person graded papers for x hours'
 * *************/

void Instructor::do_work()
{
	int work = rangedRand(1,12);
	std::cout << name << " graded papers for " << work << " hours." << std::endl;

}

/***************
 * infoPrint
 * prints out data for object
 * *************/
void Instructor::infoPrint()
{
	Menu menu;
	menu.stringResult("Name: ",name);
	menu.intResult("Age: ",age);
	menu.intResult("Rating: ",rating);
}


Student.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#include "randNum.hpp"
#include "getNum.hpp"
#include "Person.hpp"
#include "Student.hpp"
#include "Menu.hpp"
#include <iostream>
/****************
 *Student
 *constructor that updates object with user input
*****************/

Student::Student(std::string nameIn, int ageIn, int score)
{
	name=nameIn;
	age=ageIn;
	GPA=score;
}
 
/****************
 * setGPA
 * sets member variable GPA
 * *************/

double Student::setGPA()
{
	std::cout << "What is this student's GPA?";
	do
	{
		GPA=getDouble();
		if (GPA<0.0 || GPA>4.0)
		{
			std::cout << "Double selected is out of range";
		}
	}while (GPA<0.0 || GPA>4.0);
	return GPA;
}

/****************
 * do_work
 * generates a random number, then outputs message that 'person did x hours of homework'
 * **************/

void Student::do_work()
{
	int work = rangedRand(1,12);
	std::cout << name << " did " << work << " hours of homework." << std::endl;
}

/****************
 * infoPrint
 * prints info for the student object
 * ***************/

void Student::infoPrint()
{
	Menu menu;
	menu.stringResult("Name: ",name);
	menu.intResult("Age: ",age);
	menu.intResult("GPA: ",GPA);
}
Last edited on
Where are your default constructors for the 3 classes?

In each class you defined one constructor that takes 3 parameters. You declared two constructors.

You did not define the constructors that takes no parameters. Building::Building(), Student::Student() and Instructor::Instructor().
I asked around to some of my other classmates working on this assignment as well, and the error was coming up because I didn't explicitly list that I had a default constructor in my function definitions.
Topic archived. No new replies allowed.