Thread: Symbol referencing errors?

  1. #1
    Registered User
    Join Date
    Dec 2006
    Posts
    9

    Symbol referencing errors?

    Hi,

    Newbie here, trying to compile with g++ and getting these errors:

    Undefined first referenced
    symbol in file
    typeinfo for Student student.o
    vtable for Student student.o
    ld: fatal: Symbol referencing errors. No output written to student

    I've seen people posting this problem all over the web but haven't found anything that I can understand! Here's my header file:

    Code:
    #include <iostream>
    #include <fstream>
    using namespace std;
    
    class Student
    {
    public:
            virtual void Print(ostream& os);
            virtual double Average(){};
            Student(){};
            virtual char GetSubject(){};
    protected:
            Student(char* first, char* last, char sub);
            char firstName[21];
            char lastName[21];
            char subject;
    };
    
    class English : public Student
    {
    public:
            English(char* first, char* last, char sub, int atten, int proj, int mid, int final);
            double Average();
            char GetSubject();
            void Print(ostream& os);
    private:
            int attendance;
            int project;
            int midterm;
            int finalExam;
    };
    
    class History : public Student
    {
    public:
            History(char* first, char* last, char sub, int p, int mid, int final);
            double Average();
            char GetSubject();
            void Print(ostream& os);
    private:
            int paper;
            int midterm;
            int finalExam;
    };
    
    class Math : public Student
    {
    public:
            Math(char* first, char* last, char sub, int q1, int q2, int q3, int q4, int q5, int t1, int t2, int final); 
            double Average();
            char GetSubject();
            void Print(ostream& os);
    private:
            double quizAvg;
            int test1;
            int test2;
            int finalExam;
    };
    ... my definitions:
    Code:
    #include <iostream>
    #include <cstring>
    #include <fstream>
    #include "student.h"
    
    using namespace std;
    
    Student::Student(char* first, char* last, char sub)
    {
        strcpy(firstName, first);
        strcpy(lastName, last);
        subject = sub;
    }
    
    English::English(char* first, char* last, char sub, int atten, int proj, int mid, int final):
            Student(first, last, sub)
    {
        attendance = atten;
        project = proj;
        midterm = mid;
        finalExam = final;
    }
    
    char English::GetSubject()
    {
    
    }
    
    void English::Print(ostream& os)
    {
        char* fullName = strcat(firstName, " ");
        fullName = strcat(fullName, lastName);
        os.width(42);
        os << fullName;
        os.width(8);
        os << finalExam;
        os.width(8);
        os << Average();
        switch (static_cast<int>(Average()) / 10)
        {
            case 10:
            case 9:
                os << 'A';
                break;
            case 8:
                os << 'B';
                break;
            case 7:
                os << 'C';
                break;
            case 6:
                os << 'D';
                break;   
            default:    
                os << 'E';
        }
        os << '\n';  
    }
    
    double English::Average()
    {
        return static_cast<double>(attendance + project*3 + midterm*3 + finalExam*3)/1000;
    }
    
    History::History(char* first, char* last, char sub, int p, int mid, int final):
            Student(first, last, sub)
    {
        paper = p;
        midterm = mid;
        finalExam = final;
    }
    
    char History::GetSubject()
    {
    
    }
    
    void History::Print(ostream& os)
    {
        char* fullName = strcat(firstName, " ");
        fullName = strcat(fullName, lastName);
        os.width(42);
        os << fullName;
        os.width(8);
        os << finalExam;
        os.width(8);
        os << Average();
        switch (static_cast<int>(Average()) / 10)
        {
            case 10:
            case 9:
                os << 'A';
                break;
            case 8:
                os << 'B';
                break;
            case 7:
                os << 'C';
                break;
            case 6:
                os << 'D';
                break;   
            default:    
                os << 'E';
        }
        os << '\n';  
    }
    
    double History::Average()
    {
        return static_cast<double>(paper*25 + midterm*35 + finalExam*40)/10000;
    }
    
    Math::Math(char* first, char* last, char sub, int q1, int q2, int q3, int q4, int q5, int t1, int t2, int final):
            Student(first, last, sub)
    {
        quizAvg = (q1, q2, q3, q4, q5)/5;    
        test1 = t1;
        test2 = t2;
        finalExam = final;
    }
    
    char Math::GetSubject()
    {
    
    }
    
    void Math::Print(ostream& os)
    {
        char* fullName = strcat(firstName, " ");
        fullName = strcat(fullName, lastName);
        os.width(42);
        os << fullName;
        os.width(8);
        os << finalExam;
        os.width(8);
        os << Average();
        switch (static_cast<int>(Average())/10)
        {
            case 10:
            case 9:
                os << 'A';
                break;
            case 8:
                os << 'B';
                break;
            case 7:
                os << 'C';
                break;
            case 6:
                os << 'D';
                break;   
            default:    
                os << 'E';
        }
        os << '\n';  
    }
    
    double Math::Average()
    {
        return static_cast <double>(quizAvg*15 + test1*25 + test2*25 + finalExam*35)/10000;
    }
    ... and just in case it matters, my main file and makefile:
    Code:
    #include <iostream>
    #include <fstream>
    #include <cstring>
    #include "student.h"
    
    using namespace std;
    
    void PrintHeader(ofstream& os, char sub);
    
    int main()
    {
        char first[21], last[21], fullName[42], subject;
        char* inFilename, *outFilename;
        int size, a, b, c, d, e, f, g, h, numE = 0, numH = 0, numM = 0;
    
        ifstream in1;
        ofstream out1;
    
        cout << "Please enter the name of the input file.\nFilename: ";
        cin >> inFilename;
    
        cout << "Please enter the name of the output file.\nFilename: ";
        cin >> outFilename;
    
        in1.open(inFilename);
        out1.open(outFilename);
    
        if (!in1)
        {
            cout << "Error: invalid input file name.\n";
            exit(0);
        }
    
        in1 >> size;        // read first line (size of file)
                            // and declare new list of size
        Student *list = new Student[size];
    
        for (int i = 0; i < size; i++)
        {
            in1 >> first >> last >> subject;
    
            if (subject == 'E')
            {
                in1 >> a >> b >> c >> d;
                English e(first, last, subject, a, b, c, d);
                list[i] = e;
                numE++;
            }
            if (subject == 'H')
            {
                in1 >> a >> b >> c;
                History h(first, last, subject, a, b, c);
                list[i] = h;
                numH++;
            }
            if (subject =='M')
            {
                in1 >> a >> b >> c >> d >> e >> g >> h;
                Math m(first, last, subject, a, b, c, d, e, f, g, h);
                list[i] = m;
                numM++;
            }
        }
    
    // print to output file
        out1 << "Student Grade Summary\n---------------------\n\n";
    
        if (numE != 0)
        {
            PrintHeader(out1, 'E');
            for (int i = 0; i < size; i++)
            {
                if (list[i].GetSubject() == 'E')
                    list[i].Print(out1);
            }
        }
        if (numH != 0)
        {
            PrintHeader(out1, 'H');
            for (int i = 0; i < size; i++)
            {
                if (list[i].GetSubject() == 'H')
                    list[i].Print(out1);
            } 
        }
        if (numM != 0)
        {
            PrintHeader(out1, 'M');
            for (int i = 0; i < size; i++)
            {
                if (list[i].GetSubject() == 'M')
                    list[i].Print(out1);
            } 
        }
    
        delete[] list;
        in1.close();
        out1.close();
    
        return 0;
    }
    
    void PrintHeader(ofstream& os, char sub)
    {
        os << '\n';
        if (sub == 'E')
            os << "ENGLISH CLASS\n\n";
        else if (sub == 'H')
            os << "HISTORY CLASS\n\n";
        else
            os << "MATH CLASS\n\n";
     
        os.width(42);
        os << "Student";
        os.width(8);
        os << "Final";
        os.width(8);
        os << "Final";
        os << "Letter\n";
        os.width(42);
        os << "Name";
        os.width(8);
        os << "Exam";
        os.width(8);
        os << "Avg";
        os << "Grade\n----------------------------------------------------------------\n";
    
    }
    Code:
    student: student.o main.o
            g++ -o student student.o main.o
    
    student.o: student.cpp student.h
            g++ -c student.cpp
    
    main.o: main.cpp student.h
            g++ -c main.cpp
    
    clean:
            rm -f *.o student
    I'd appreciate any help.
    Last edited by lisa1901; 04-01-2007 at 08:25 PM.

  2. #2
    Registered User
    Join Date
    May 2006
    Posts
    903
    Add this code, it's called header guards.

    Code:
    #ifndef STUDENT_H_INCLUDED
    #define STUDENT_H_INCLUDED
    
    // your code here
    
    #endif
    I'm going to bed right now and I don't really feel like explaining today (probably tomorrow) but this should let you at least be able to compile your program without errors.

  3. #3
    Registered User
    Join Date
    Dec 2006
    Posts
    9
    I emailed my professor and he said I just needed to add braces after that virtual function in the base class Student (the one that I missed, apparently). It compiles now. But thanks for the response.

  4. #4
    Registered User
    Join Date
    Feb 2006
    Posts
    43
    Unless a function is "pure virtual," which your Student's Print function isn't, you need to define it. You should either come up with a simple definition, or just put
    Code:
    {}
    after the declaration like you did with your other virtual functions.
    -Crazed

    EDIT: oops looks like you and your prof beat me to it

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Compiling sample DarkGDK Program
    By Phyxashun in forum Game Programming
    Replies: 6
    Last Post: 01-27-2009, 03:07 AM
  2. Including lib in a lib
    By bibiteinfo in forum C++ Programming
    Replies: 0
    Last Post: 02-07-2006, 02:28 PM
  3. Stupid compiler errors
    By ChrisEacrett in forum C++ Programming
    Replies: 9
    Last Post: 11-30-2003, 05:44 PM
  4. Linking error
    By DockyD in forum C++ Programming
    Replies: 10
    Last Post: 01-20-2003, 05:27 AM
  5. <list>
    By Unregistered in forum C++ Programming
    Replies: 9
    Last Post: 02-24-2002, 04:07 PM