我正在C++中实现非均匀链表(.cpp和.h文件如下(。
使用英特尔编译器icpc test.cpp List.cpp -o test
在Linux中编译会产生很多错误(请参阅下文(。问题似乎源于List.cpp
中包含dynamic_cast
的行。在我看来,语法是正确的。有人能帮我找出问题吗?
/tmp/icpcIuHg7X.o: In function `InhomList::getPrev(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)':
List.cpp:(.text+0x25): undefined reference to `typeinfo for BaseEl'
/tmp/icpcIuHg7X.o: In function `InhomList::getPos(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)':
List.cpp:(.text+0x134): undefined reference to `typeinfo for BaseEl'
/tmp/icpcIuHg7X.o: In function `InhomList::insertAfter(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, Cell*)':
List.cpp:(.text+0x267): undefined reference to `vtable for BaseEl'
List.cpp:(.text+0x346): undefined reference to `vtable for BaseEl'
/tmp/icpcIuHg7X.o: In function `InhomList::insertAfter(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, Cell*)':
List.cpp:(.text+0x43b): undefined reference to `vtable for BaseEl'
List.cpp:(.text+0x4c8): undefined reference to `vtable for DerivedEl'
List.cpp:(.text+0x59c): undefined reference to `BaseEl::~BaseEl()'
List.cpp:(.text+0x5c9): undefined reference to `vtable for BaseEl'
List.cpp:(.text+0x659): undefined reference to `vtable for DerivedEl'
List.cpp:(.text+0x71c): undefined reference to `BaseEl::~BaseEl()'
/tmp/icpcIuHg7X.o: In function `InhomList::erasePos(Cell*)':
List.cpp:(.text+0x756): undefined reference to `typeinfo for BaseEl'
/tmp/icpcIuHg7X.o: In function `InhomList::InhomList(InhomList const&)':
List.cpp:(.text+0x8c3): undefined reference to `typeinfo for DerivedEl'
List.cpp:(.text+0x8d5): undefined reference to `typeinfo for DerivedEl'
List.cpp:(.text+0x915): undefined reference to `typeinfo for DerivedEl'
List.cpp:(.text+0x97c): undefined reference to `typeinfo for BaseEl'
List.cpp:(.text+0xa61): undefined reference to `vtable for BaseEl'
List.cpp:(.text+0xaf4): undefined reference to `vtable for DerivedEl'
List.cpp:(.text+0xb7c): undefined reference to `typeinfo for BaseEl'
List.cpp:(.text+0xc97): undefined reference to `vtable for BaseEl'
List.cpp:(.text+0xd4d): undefined reference to `BaseEl::~BaseEl()'
List.cpp:(.text+0xdad): undefined reference to `vtable for BaseEl'
List.cpp:(.text+0xe4a): undefined reference to `vtable for DerivedEl'
List.cpp:(.text+0xf1c): undefined reference to `BaseEl::~BaseEl()'
List.cpp:(.text+0xf7b): undefined reference to `vtable for BaseEl'
/tmp/icpcIuHg7X.o: In function `InhomList::InhomList(InhomList const&)':
List.cpp:(.text+0x1063): undefined reference to `typeinfo for DerivedEl'
List.cpp:(.text+0x1075): undefined reference to `typeinfo for DerivedEl'
List.cpp:(.text+0x10b5): undefined reference to `typeinfo for DerivedEl'
List.cpp:(.text+0x111c): undefined reference to `typeinfo for BaseEl'
List.cpp:(.text+0x1201): undefined reference to `vtable for BaseEl'
List.cpp:(.text+0x1294): undefined reference to `vtable for DerivedEl'
List.cpp:(.text+0x131c): undefined reference to `typeinfo for BaseEl'
List.cpp:(.text+0x1437): undefined reference to `vtable for BaseEl'
List.cpp:(.text+0x14ed): undefined reference to `BaseEl::~BaseEl()'
List.cpp:(.text+0x154d): undefined reference to `vtable for BaseEl'
List.cpp:(.text+0x15ea): undefined reference to `vtable for DerivedEl'
List.cpp:(.text+0x16bc): undefined reference to `BaseEl::~BaseEl()'
List.cpp:(.text+0x171b): undefined reference to `vtable for BaseEl'
/tmp/icpcIuHg7X.o: In function `InhomList::operator=(InhomList const&)':
List.cpp:(.text+0x18eb): undefined reference to `typeinfo for DerivedEl'
List.cpp:(.text+0x18fd): undefined reference to `typeinfo for DerivedEl'
List.cpp:(.text+0x193d): undefined reference to `typeinfo for DerivedEl'
List.cpp:(.text+0x19a4): undefined reference to `typeinfo for BaseEl'
List.cpp:(.text+0x1a89): undefined reference to `vtable for BaseEl'
List.cpp:(.text+0x1b1c): undefined reference to `vtable for DerivedEl'
List.cpp:(.text+0x1ba4): undefined reference to `typeinfo for BaseEl'
List.cpp:(.text+0x1cbf): undefined reference to `vtable for BaseEl'
List.cpp:(.text+0x1d79): undefined reference to `BaseEl::~BaseEl()'
List.cpp:(.text+0x1dd9): undefined reference to `vtable for BaseEl'
List.cpp:(.text+0x1e76): undefined reference to `vtable for DerivedEl'
List.cpp:(.text+0x1f48): undefined reference to `BaseEl::~BaseEl()'
List.cpp:(.text+0x1fa7): undefined reference to `vtable for BaseEl'
/tmp/icpcIuHg7X.o: In function `InhomList::insert(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)':
List.cpp:(.text+0x2086): undefined reference to `typeinfo for BaseEl'
List.cpp:(.text+0x2160): undefined reference to `vtable for BaseEl'
List.cpp:(.text+0x223f): undefined reference to `vtable for BaseEl'
/tmp/icpcIuHg7X.o: In function `InhomList::insert(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)':
List.cpp:(.text+0x231b): undefined reference to `typeinfo for BaseEl'
List.cpp:(.text+0x23f7): undefined reference to `vtable for BaseEl'
List.cpp:(.text+0x2488): undefined reference to `vtable for DerivedEl'
List.cpp:(.text+0x2560): undefined reference to `BaseEl::~BaseEl()'
List.cpp:(.text+0x258e): undefined reference to `vtable for BaseEl'
List.cpp:(.text+0x261f): undefined reference to `vtable for DerivedEl'
List.cpp:(.text+0x26e6): undefined reference to `BaseEl::~BaseEl()'
/tmp/icpcIuHg7X.o: In function `InhomList::erase(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)':
List.cpp:(.text+0x2716): undefined reference to `typeinfo for BaseEl'
List.cpp:(.text+0x2789): undefined reference to `typeinfo for BaseEl'
List.cpp:(.text+0x279f): undefined reference to `typeinfo for BaseEl'
List.cpp:(.text+0x27e6): undefined reference to `typeinfo for BaseEl'
List.cpp:(.text+0x27f8): undefined reference to `typeinfo for BaseEl'
/tmp/icpcIuHg7X.o:List.cpp:(.text+0x281c): more undefined references to `typeinfo for BaseEl' follow
test.cpp:程序
#include "List.h"
#include <typeinfo>
int main() {
return 0;
}
cell.h:定义类cell、BaseEl和DerivedEl
// --------------------------------------------------------
#ifndef _CELL_
#define _CELL_
#include <string>
#include <iostream>
using namespace std;
// Abstract class
class Cell {
private:
Cell *next;
protected:
Cell(Cell *suc = NULL) :
next(suc) {
;
}
public:
virtual ~Cell() {
}
// Access methods:
Cell* getNext(void) const {
return next;
}
void setNext(Cell *suc) {
next = suc;
}
virtual void display() const = 0;
};
class BaseEl: public Cell {
private:
string name;
public:
BaseEl(Cell *suc = NULL, const string &s = "") :
Cell(suc), name(s) {
;
}
~BaseEl();
// Access methods:
const string& getName(void) const {
return name;
}
void setName(const string &s) {
name = s;
}
void display() const {
cout << endl << "------------------------------" << endl << "Name: "
<< name << endl;
}
};
class DerivedEl: public BaseEl {
private:
string rem;
public:
DerivedEl(Cell *suc = NULL, const string &s = "", const string &b = "") :
BaseEl(suc, s), rem(b) {
;
}
~DerivedEl();
// Access methods:
const string& getRem(void) {
return rem;
}
void setRem(const string &s) {
rem = s;
}
void display() const {
BaseEl::display();
cout << "Remark: " << rem << endl;
}
};
#endif
List.h:定义类InhomList.h
// --------------------------------------------------------
#ifndef _LIST_
#define _LIST_
#include "cell.h"
using namespace std;
class InhomList {
private:
Cell *first;
protected:
Cell* getPrev(const string &s);
Cell* getPos(const string &s);
void insertAfter(const string &s, Cell *prev);
void insertAfter(const string &s, const string &b, Cell *prev);
void erasePos(Cell *pos);
public:
InhomList() {
first = NULL;
}
InhomList(const InhomList &src);
~InhomList();
InhomList& operator=(const InhomList &src);
void insert(const string &n);
void insert(const string &n, const string &b);
void erase(const string &n);
void displayAll() const;
};
#endif
List.cpp:List.h 的方法
#include "List.h"
#include <typeinfo>
// Copy constructor:
InhomList::InhomList(const InhomList &src) {
// Append the elements from src to the empty list.
first = NULL;
Cell *pEl = src.first;
for (; pEl != NULL; pEl = pEl->getNext()) {
if (typeid(*pEl) == typeid(DerivedEl)) {
insert(dynamic_cast<DerivedEl*>(pEl)->getName(),
dynamic_cast<DerivedEl*>(pEl)->getRem());
} else
insert(dynamic_cast<BaseEl*>(pEl)->getName());
}
}
// Destructor:
InhomList::~InhomList() {
Cell *pEl = first, *next = NULL;
while (pEl != NULL) {
next = pEl->getNext();
delete pEl;
pEl = next;
}
}
// Assignment:
InhomList& InhomList::operator=(const InhomList &src) {
// To free storage for all elements:
Cell *pEl = first, *next = NULL;
while (pEl != NULL) {
next = pEl->getNext();
delete pEl;
pEl = next;
}
first = NULL; // Empty list
pEl = src.first; // Copy the elements from src to the empty list
for (; pEl != NULL; pEl = pEl->getNext())
if (typeid(*pEl) == typeid(DerivedEl))
insert(dynamic_cast<DerivedEl*>(pEl)->getName(),
dynamic_cast<DerivedEl*>(pEl)->getRem());
else
insert(dynamic_cast<BaseEl*>(pEl)->getName());
return *this;
}
void InhomList::insert(const string &n) {
Cell *pEl = getPrev(n);
insertAfter(n, pEl);
}
void InhomList::insert(const string &n, const string &b) {
Cell *pEl = getPrev(n);
insertAfter(n, b, pEl);
}
void InhomList::erase(const string &n) {
erasePos(getPos(n));
}
void InhomList::displayAll() const {
Cell *pEl = first;
while (pEl != NULL) {
pEl->display();
pEl = pEl->getNext();
}
}
Cell* InhomList::getPrev(const string &n) {
Cell *pEl = first, *prev = NULL;
while (pEl != NULL) {
if (n > dynamic_cast<BaseEl*>(pEl)->getName()) {
prev = pEl;
pEl = pEl->getNext();
} else
return prev;
}
return prev;
}
Cell* InhomList::getPos(const string &n) {
Cell *pEl = first;
while (pEl != NULL && (n != dynamic_cast<BaseEl*>(pEl)->getName()))
pEl = pEl->getNext();
if (pEl != NULL && n == dynamic_cast<BaseEl*>(pEl)->getName())
return pEl;
else
return NULL;
}
void InhomList::insertAfter(const string &s, Cell *prev) {
if (prev == NULL) // Insert at the beginning:
first = new BaseEl(first, s);
else // In the middle or at the end:
{
Cell *p = new BaseEl(prev->getNext(), s);
prev->setNext(p);
}
}
void InhomList::insertAfter(const string &s, const string &b, Cell *prev) {
if (prev == NULL) // Insert at the beginning:
first = new DerivedEl(first, s, b);
else // In the middle or at the end:
{
Cell *p = new DerivedEl(prev->getNext(), s, b);
prev->setNext(p);
}
}
void InhomList::erasePos(Cell *pos) {
Cell *temp;
if (pos != NULL)
if (pos == first) // Delete the first element
{
temp = first;
first = first->getNext();
delete temp;
} else // Delete from the middle or at the end
{ // Get the predecessor
temp = getPrev(dynamic_cast<BaseEl*>(pos)->getName());
if (temp != NULL) // and bend pointer.
temp->setNext(pos->getNext());
delete pos;
}
}
您可以从修复此错误开始:
undefined reference to `BaseEl::~BaseEl()'
发生此错误是因为您声明了BaseEl::~BaseEl()
:
~BaseEl();
但你没有给出定义。您可以将定义提供为~BaseEl() override {}
或~BaseEl() override = default;
,也可以在cell.cpp
或类似文件中进行越界定义。
同样,您需要确保为DerivedEl::~DerivedEl()
提供了一个定义。
如果我没有错的话,提供这些定义将消除"对vtable的未定义引用"one_answers"对typeinfo的未定义参考"错误。有关可能的解释,请参见此处。