c++ undefined reference to `vtable

14,382

Solution 1

What compiler are you using? Visual Studio 2010 gives this more helpful output:

1>cachesize.obj : error LNK2019: unresolved external symbol "public: virtual __thiscall arrayListType::~arrayListType(void)" (??1arrayListType@@UAE@XZ) referenced in function "public: virtual void * __thiscall arrayListType::`scalar deleting destructor'(unsigned int)" (??_GarrayListType@@UAEPAXI@Z)

1>cachesize.obj : error LNK2019: unresolved external symbol "public: virtual __thiscall orderedArrayListType::~orderedArrayListType(void)" (??1orderedArrayListType@@UAE@XZ) referenced in function "public: virtual void * __thiscall orderedArrayListType::`scalar deleting destructor'(unsigned int)" (??_GorderedArrayListType@@UAEPAXI@Z) 1>C:\Users\james\Documents\Visual Studio 2010\Projects\cachesize\Debug\cachesize.exe : fatal error LNK1120: 2 unresolved externals

You need to add bodies to virtual ~arrayListType(); and ~orderedArrayListType();.
You've declared them but not defined them. It compiles then!

Solution 2

You're missing the destructor definitions:

arrayListType::~arrayListType() { }

orderedArrayListType::~orderedArrayListType() { }

Linker errors are usually not very useful. But this exact error is usually generated when you declare, but don't define, your destructor.

Share:
14,382
Jeff
Author by

Jeff

Updated on June 27, 2022

Comments

  • Jeff
    Jeff almost 2 years

    My question has changed from the other one I have posted. I started out with multiple files and decided to put it all in one main.cpp file for now just to get it working.

    main.cpp:

    #include <iostream>
    using namespace std;
    
    class arrayListType {
        public:
            bool isEmpty() ;
            bool isFull() ;
            int listSize() ;
            int maxListSize() ;
            void print() ;
            bool isItemAtEqual(int location, int item) ;
            virtual void insertAt(int location, int insertItem) = 0;
            virtual void insertEnd(int insertItem) = 0;
            void removeAt(int location);
            void retrieveAt(int location, int& retItem) ;
            virtual void replaceAt(int location, int repItem) = 0;
            void clearList();
            virtual int seqSearch(int searchItem) const  = 0;
            virtual void remove(int removeItem) = 0;
            arrayListType (int size = 100);
            arrayListType ( arrayListType& otherList);
            virtual ~arrayListType();
        protected:
            int *list;
            int length;
            int maxSize;
    };
    
    
    bool arrayListType::isEmpty()  {
        return (length == 0);
    }
    bool arrayListType::isFull()  {
        return (length == maxSize);
    }
    int arrayListType::listSize()  {
        return length;
    }
    int arrayListType::maxListSize()  {
        return maxSize;
    }
    void arrayListType::print()  {
        for (int i = 0; i < length; i++)
            cout << list[i] << " ";
        cout << endl;
    }
    bool arrayListType::isItemAtEqual(int location, int item)  {
        if (location < 0 || location >= length) {
            cout << "The location of the item to be compared is out range." << endl;
            return false;
        }
        else
            return(list[location] == item);
    }
    
    
    void arrayListType::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--;
        }
    }
    void arrayListType::retrieveAt(int location, int& retItem)  {
        if (location < 0 || location >= length) {
            cout << "The location of the item to be retrieved is out of range." << endl;
        }
        else
            retItem = list[location];
    }
    
    
    void arrayListType::clearList() {
        length = 0;
    }
    
    
    arrayListType::arrayListType (int size) {
        if (size <= 0) {
            cout << "The array size must be positive. Creating an array of the size 100." << endl;
            maxSize = 100;
        }
        else
            maxSize = size;
        length = 0;
        list = new int[maxSize];
    }
    
    class orderedArrayListType: public arrayListType {
    
        public:
            void insertAt(int location, int insertItem);
            void insertEnd(int insertItem);
            void replaceAt(int location, int repItem);
            int seqSearch(int searchItem) const;
            void insert (int insertItem);
            void remove (int removeItem);
            orderedArrayListType (int size = 100);
            ~orderedArrayListType();
        private:
            void quickSort();
    };
    
    
    
    void orderedArrayListType::quickSort(){
    //private function for sorting "list."
    //using a "quicksort" method
    //addapted from: http://www.algolist.net/Algorithms/Sorting/Quicksort
        if (length == 0) {
            cout << "Cannot sort an ampty list." << endl;
        }
        else {
            int left = 0, right = length;
            int i = left, j = right;
        int tmp;
        int pivot = list[(left + right) / 2];
        /* partition */
        while (i <= j) {
            while (list[i] < pivot)
                i++;
            while (list[j] > pivot)
                j--;
            if (i <= j) {
                tmp = list[i];
                list[i] = list[j];
                list[j] = tmp;
                i++;
                j--;
            }
        };
        /* recursion */
        if (left < j)
            quickSort();
        if (i < right)
            quickSort();
        }
    }
    
    
    
    
    void orderedArrayListType::insertAt(int location, int insertItem){
    
        if (location < 0 || location >= length){
            cout << "The location of the item to be removed "
            << "is out of range." << endl;
        }
        else if(length == maxSize){
            cout << "Cannot insert in a full list." << endl;
        }
        else {
            for (int j = length; j < location; j--){ 
                list[j+1] = list[j]; 
                /* 
                Start at the end of the array and move each item 
                out by one. Coninue until list[j] is at the 
                location, then set the list[location] to the value.
                */  
            }
            list[location] = insertItem;
            length++;
        }
        quickSort();
    }
    
    void orderedArrayListType::insertEnd(int insertItem) {
    
        if (length == maxSize){
            cout << "Cannot insert in a full list." << endl;
        }
        else {
            list[length] = insertItem;
            length++;
        }
        quickSort();
    }
    
    
    void orderedArrayListType::replaceAt(int location, int repItem) {
        if (location < 0 || location >= length){
            cout << "The location of the item to be replaced "
            << "is out of range." << endl;
        }
        else
            list[location] = repItem;
        quickSort();
    }
    
    int orderedArrayListType::seqSearch(int searchItem) const {
    
        int loc;
        bool found = false;
        loc = 0;
        while (loc < length && !found) {
            if (list[loc] == searchItem)
                found = true;
            else
                loc++;
        }
        if (found)
            return loc;
        else
            return -1;
    }
    
    
    void orderedArrayListType::insert (int insertItem){
        if (length == 0){
            list[length++] = insertItem;
        }
        else if (length == maxSize){
            cout << "Cannot insert in a full list." << endl;
        }
        else {
            int loc;
            bool found = false;
            for (loc= 0; loc < length; loc++){
                if (list[loc] >= insertItem){
                    found = true;
                    break;
                }
            }
            for (int i = length; i > loc; i--) {
                list[i] = list[i-1];
            }
            list[loc] = insertItem;
            length++;
        }
        quickSort();
    }
    void orderedArrayListType::remove (int removeItem) {
    
        int loc;
    
        if (length == 0)
            cout << "Cannot Delete from an ampty list." << endl;
        else {
            loc = seqSearch(removeItem);
            if (loc != -1)
                removeAt(loc);
            else
                cout << "The item to be deleted is not in the list." << endl;
        }
    }
    
    
    orderedArrayListType::orderedArrayListType (int size)
        :arrayListType(size){
    }
    
    
    
    
    
    int main() {
    
    //  orderedArrayList intlist(25);
    //  orderedArrayListType intList = new orderedArrayListType(25);
    }
    

    The exact error message:

    /tmp/ccdTFaE0.o: In function arrayListType::arrayListType(int)': main3.cpp:(.text+0x25c): undefined reference tovtable for arrayListType' /tmp/ccdTFaE0.o:(.rodata._ZTV20orderedArrayListType[vtable for orderedArrayListType]+0
    x38): undefined reference to orderedArrayListType::~orderedArrayListType()' /tmp/ccdTFaE0.o:(.rodata._ZTV20orderedArrayListType[vtable for orderedArrayListType]+0
    x40): undefined reference to
    orderedArrayListType::~orderedArrayListType()' /tmp/ccdTFaE0.o:(.rodata._ZTI20orderedArrayListType[typeinfo for orderedArrayListType]
    +0x10): undefined reference to `typeinfo for arrayListType' collect2: ld returned 1 exit status

    tldr;

    #include <iostream>
    using namespace std;
    
    class arrayListType {
        public:
            bool isEmpty() const;
                    ...
                    arrayListType (int size = 100);
            arrayListType ( arrayListType& otherList);
            virtual ~arrayListType();
        protected:
            int *list;
            int length;
            int maxSize;
    };
    
    
    //definitions 
    bool arrayListType::isEmpty()  {
        return (length == 0);
    }
    
    class orderedArrayListType: public arrayListType {
    
        public:
            void insertAt(int location, int insertItem);
            ...
            orderedArrayListType (int size = 100);
            ~orderedArrayListType();
        private:
            void quickSort();
    };
    
    
    
    void orderedArrayListType::quickSort(){
     ...
     }
    
    
    
    
    void orderedArrayListType::insertAt(int location, int insertItem){
    
           ....     
    
        quickSort();
    }
    
       orderedArrayListType::orderedArrayListType (int size)
        :arrayListType(size){
    }
    
    
    int main() {
    
        orderedArrayList intlist(25);
    //  orderedArrayListType intList = new orderedArrayListType(25);
    }
    
  • Jeff
    Jeff over 11 years
    It compiled! Now if I try to uncoment out the "orderedArrayList intlist(25);" line in the "int main()" it errors out.
  • James
    James over 11 years
    @Jeff It should be orderedArrayListType
  • James
    James over 11 years
    @Jeff and the second one that's commented out should be orderedArrayListType*
  • Andres Felipe
    Andres Felipe over 10 years
    In general one may obtain this error in the case where a method is declared but not defined.