C++未定义对`vtable的引用

4

我的问题与我之前发布的不同。一开始我有多个文件,但决定将它们全部放在一个main.cpp文件中,以便先让它工作。

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

确切的错误信息如下:
/tmp/ccdTFaE0.o: 在函数 'arrayListType::arrayListType(int)' 中: main3.cpp:(.text+0x25c): 未定义对 'vtable for arrayListType' 的引用 /tmp/ccdTFaE0.o:(.rodata._ZTV20orderedArrayListType[vtable for orderedArrayListType]+0x38):undefined reference to 'orderedArrayListType::~orderedArrayListType()' /tmp/ccdTFaE0.o:(.rodata._ZTV20orderedArrayListType[vtable for orderedArrayListType]+0x40):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
简要概括:在运行程序时,出现了无法识别的引用、未定义的析构函数等问题。
#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
认真的说 - 你想让我为你调试263行代码吗?请把示例简化成我愿意阅读的内容。 - Adrian Cornish
2
听起来像是缺少析构函数的定义。 - Tony K.
1
@Jeff编辑问题并粘贴代码。 - mfontanini
你发帖前没有进行快速搜索的原因是什么?你的问题是传统的“未实现虚析构函数”的问题,所有在此问题右侧的链接都可以解决。 - kfsone
你意识到自从我最初发布这个帖子已经一年过去了,对吧? - Jeff
显示剩余5条评论
2个回答

7

你缺少析构函数的定义:

arrayListType::~arrayListType() { }

orderedArrayListType::~orderedArrayListType() { }

链接错误通常不是非常有用的。但是当您声明但未定义析构函数时,通常会生成此确切错误。

1
通常情况下,当一个方法被声明但未定义时,可能会出现这个错误。 - Andres Felipe

4
您使用的是哪个编译器?Visual Studio 2010 提供了更有帮助的输出信息:
1>cachesize.obj : 错误 LNK2019:无法解析的外部符号 "public: virtual __thiscall arrayListType::~arrayListType(void)" (??1arrayListType@@UAE@XZ),该符号在函数 "public: virtual void * __thiscall arrayListType::`scalar deleting destructor'(unsigned int)" (??_GarrayListType@@UAEPAXI@Z) 中被引用 1>cachesize.obj : 错误 LNK2019:无法解析的外部符号 "public: virtual __thiscall orderedArrayListType::~orderedArrayListType(void)" (??1orderedArrayListType@@UAE@XZ),该符号在函数 "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 : 致命错误 LNK1120: 2 个无法解析的外部命令
您需要为 virtual ~arrayListType();~orderedArrayListType(); 添加函数体。您已经声明了它们,但没有定义。这样就可以编译了!

编译成功了!现在如果我尝试在“int main()”中取消注释“orderedArrayList intlist(25);”这一行,它会报错。 - Jeff
1
@Jeff 应该是 orderedArrayListType - James
@Jeff,被注释掉的第二个应该是 orderedArrayListType* - James

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接