c++ undefined reference to `vtable

别来无恙 提交于 2019-12-12 14:20:50

问题


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);
}

回答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!




回答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.



来源:https://stackoverflow.com/questions/12327679/c-undefined-reference-to-vtable

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!