C++ 链接错误:未定义对“XXX的vtable”的引用`
这里有一些链接错误。我在网上找过,但还是找不到问题。我怎样才能修好它C++ 链接错误:未定义对“XXX的vtable”的引用`,c++,g++,C++,G++,这里有一些链接错误。我在网上找过,但还是找不到问题。我怎样才能修好它 g++ test.cpp -o test /tmp/ccDfCj4N.o: In function `Interval::Interval()': test.cpp:(.text._ZN8IntervalC2Ev[Interval::Interval()]+0x9): undefined reference to `vtable for Interval' /tmp/ccDfCj4N.o: In function `I
g++ test.cpp -o test
/tmp/ccDfCj4N.o: In function `Interval::Interval()':
test.cpp:(.text._ZN8IntervalC2Ev[Interval::Interval()]+0x9): undefined reference to `vtable for Interval'
/tmp/ccDfCj4N.o: In function `IntInterval::~IntInterval()':
test.cpp:(.text._ZN11IntIntervalD0Ev[IntInterval::~IntInterval()]+0x1d): undefined reference to `Interval::~Interval()'
/tmp/ccDfCj4N.o: In function `IntInterval::~IntInterval()':
test.cpp:(.text._ZN11IntIntervalD1Ev[IntInterval::~IntInterval()]+0x1d): undefined reference to `Interval::~Interval()'
/tmp/ccDfCj4N.o:(.rodata._ZTI11IntInterval[typeinfo for IntInterval]+0x10): undefined reference to `typeinfo for Interval'
collect2: ld returned 1 exit status
这是密码!
对于试点项目,所有类都在同一个文件中
#include <iostream>
#include <vector>
#include <utility>
using namespace std;
#define MAX_IP_RANGE 4294967295
class Interval {
public:
virtual Interval * interval_copy() = 0;
virtual unsigned long get_begin() = 0;
virtual unsigned long get_end() = 0;
virtual unsigned long get_length() = 0;
virtual Interval* get_intersect(Interval *interval) = 0; // Examine whether two intervals have intersection
virtual Interval* copy() = 0;
virtual ~Interval();
virtual bool is_equal(Interval *interval) {
unsigned long b1 = this->get_begin();
unsigned long e1 = this->get_end();
unsigned long b2 = interval->get_begin();
unsigned long e2 = interval->get_end();
if (b1 == b2 && e1 == e2)
return true;
return false;
}
virtual bool is_within(Interval *interval) {
unsigned long b1 = this->get_begin();
unsigned long e1 = this->get_end();
unsigned long b2 = interval->get_begin();
unsigned long e2 = interval->get_end();
if (b1 >= b2 && e1 <= e2)
return true;
return false;
}
virtual bool contains(Interval *interval) { // Examine whether this interval contains another interval
unsigned long b1 = this->get_begin();
unsigned long e1 = this->get_end();
unsigned long b2 = interval->get_begin();
unsigned long e2 = interval->get_end();
if (b1 <= b2 && e1 >= e2)
return true;
return false;
}
virtual bool is_empty() {
return (get_end()<get_begin())?true:false;
}
virtual bool is_intersect(Interval *interval) {
unsigned long b1 = this->get_begin();
unsigned long e1 = this->get_end();
unsigned long b2 = interval->get_begin();
unsigned long e2 = interval->get_end();
if (b1>e2)
return false;
if (b2>e1)
return false;
return true;
}
virtual void print()
{
cout << '('<<get_begin() << ',' << get_end() << ")\n";
}
};
class IntInterval : public Interval {
private:
unsigned long begin;
unsigned long end;
IntInterval();
public:
virtual Interval * interval_copy() {
return new IntInterval(begin, end);
}
IntInterval(unsigned long a, unsigned long b): begin (a), end (b)
{}
void set_value(unsigned long a, unsigned long b) {
begin = a;
end = b;
}
void set_begin(unsigned long a) {
begin = a;
}
void set_end(unsigned long b) {
end = b;
}
virtual Interval* copy()
{
Interval *new_interval = new IntInterval(begin, end);
return new_interval;
}
virtual unsigned long get_begin() {
return begin;
}
virtual unsigned long get_length() {
return end-begin+1;
}
virtual unsigned long get_end() {
return end;
}
virtual Interval* get_intersect(Interval *interval); // Get the intersect part of two intervals
virtual ~IntInterval() {};
};
Interval* IntInterval::get_intersect(Interval *interval) {
unsigned long begin2 = interval->get_begin();
unsigned long end2 = interval->get_end();
if (end < begin2 || begin > end2) {
return new IntInterval(1, 0);
}
return new IntInterval((begin>begin2)?begin:begin2, (end<end2)?end:end2);
}
IntInterval * parse_ip(const char * _str) {
unsigned long _begin=0;
unsigned long _end=0;
string input(_str);
if (input.find('-') != string::npos){
string begin = input.substr(0, input.find('-'));
string end = input.substr(input.find('-')+1);
unsigned int ip1 = 0, ip2 = 0;
unsigned int ip3 = 0, ip4 = 0;
sscanf(begin.c_str(), "%u.%u.%u.%u", &ip1, &ip2, &ip3, &ip4);
_begin = (ip1 << 24) + (ip2 << 16) + (ip3 << 8) + ip4;
ip1 = 0; ip2 = 0; ip3 = 0; ip4 = 0;
sscanf(end.c_str(), "%u.%u.%u.%u", &ip1, &ip2, &ip3, &ip4);
_end = (ip1 << 24) + (ip2 << 16) + (ip3 << 8) + ip4;
if ((_begin > _end) || (_end > MAX_IP_RANGE)){
cout<<"ERROR: The IP INTERVAL IS WRONG The range is "<<begin<<"-"<<end<<endl;
exit(0);
}
}
return new IntInterval(_begin, _end);
}
bool compFunc (Interval * i, Interval * j) {
return (i->get_begin() < j->get_begin());
}
int main () {
vector <vector<pair<string, string> > > nets;
vector<pair<string, string> > x;
vector<pair<string, string> > y;
x.push_back(make_pair("1.1.1.1", "3.0.0.0"));
x.push_back(make_pair("10.2.5.3", "30.2.5.0"));
x.push_back(make_pair("100.2.25.2", "130.2.25.2"));
y.push_back(make_pair("41.0.2.2", "43.2.2.5"));
y.push_back(make_pair("131.2.2.2", "135.5.5.2"));
nets.push_back(x);
nets.push_back(y);
vector <IntInterval *> _nets;
for (int i=0; i<(int)nets.size(); i++)
for(int j=0; j<(int)nets[i].size(); j++) {
string s = nets[i][j].first + '-' + nets[i][j].second;
_nets.push_back(parse_ip(s.c_str()));
}
sort(_nets.begin(), _nets.end(), compFunc);
if (_nets.size()>1)
for (vector<IntInterval *>::iterator it = _nets.begin()+1; it < _nets.end(); ) {
if ((*it)->get_begin()-1 == (*(it-1))->get_end()) {
(*(it-1))->set_end((*it)->get_end());
_nets.erase(it);
}
else if ((*it)->get_begin()-1 < (*(it-1))->get_end()) {
it++;
cout<<"ERROR: Network address overlapping!"<<endl;
}
else
it++;
}
for (int i=0; i<(int)_nets.size(); i++)
cout << _nets[i]->get_begin() << " " << _nets[i]->get_end() << endl;
return 0;
}
#包括
#包括
#包括
使用名称空间std;
#定义最大IP范围4294967295
课间休息{
公众:
虚拟间隔*Interval_copy()=0;
虚拟无符号长get_begin()=0;
虚拟无符号长get_end()=0;
虚拟无符号长get_length()=0;
虚拟区间*get_intersect(区间*Interval)=0;//检查两个区间是否相交
虚拟间隔*copy()=0;
虚拟区间();
虚拟布尔等于(间隔*间隔){
unsigned long b1=此->获取开始();
无符号长e1=this->get_end();
无符号长b2=间隔->获取开始();
无符号长e2=间隔->获取结束();
如果(b1==b2&&e1==e2)
返回true;
返回false;
}
虚拟布尔值在(间隔*间隔)内{
unsigned long b1=此->获取开始();
无符号长e1=this->get_end();
无符号长b2=间隔->获取开始();
无符号长e2=间隔->获取结束();
如果(b1>=b2&&e1 get_begin();
无符号长e1=this->get_end();
无符号长b2=间隔->获取开始();
无符号长e2=间隔->获取结束();
如果(b1=e2)
返回true;
返回false;
}
虚拟布尔值为_empty(){
返回(get_end()get_begin();
无符号长e1=this->get_end();
无符号长b2=间隔->获取开始();
无符号长e2=间隔->获取结束();
如果(b1>e2)
返回false;
如果(b2>e1)
返回false;
返回true;
}
虚拟空打印()
{
cout在虚拟类中,永远不要将未定义的函数放在第一位。移动
IntInterval();
在第一个定义的函数之后执行以下操作:
private:
unsigned long begin;
unsigned long end;
public:
virtual Interval * interval_copy(){return new IntInterval(begin,end);}
IntInterval(unsigned long a,unsigned long b): begin (a),
end (b)
{}
private:
IntInterval();
public:
< >因为C++对第一个函数的VTL加修饰。如果不定义它,VTALE也将是未定义的。< /P>
如其他答案所述,还需要定义析构函数:
public:
virtual ~IntInterval()
{
// Destruction code
}
您从未为virtual~Interval()提供过实现;
和其他几个函数。您必须为您声明的所有非纯虚拟函数提供一个实现。特别是,G++会在类中第一个声明的非内联函数实现的同时发出vtable。省略其实现意味着您将没有vtable,因此无法构造该类(因此出现了这些错误)
简言之,定义您声明的每个函数,除了纯虚拟函数。在某些情况下,省略声明函数的定义是有道理的,但它们非常罕见。我也遇到了同样的问题。我将代码与上游更改合并,并在头文件中选择了另一个工程师看似相同的更改。结果是他们改变了方法的常数,而我没有注意到,你会因为@bdonian说的原因得到这个错误
virtual void foo(Many params, As part, Of veryLong, Method signature);
以及他们的:
virtual void foo(Many params, As part, Of veryLong, Method signature) const;
合并时,我选择了第一个版本,但实现有第二个版本,这导致编译器假设有一个foo()重载这是未定义的,因此是错误。这不会修复任何问题。您仍然需要定义您声明的函数。他缺少几个虚拟函数的定义,因此即使您设法让G++发出vtable,vtable本身也会导致未定义虚拟体的更多链接错误。@bdonlan:这将使未定义vt可以让
离开。他不需要定义他不使用的函数。是的,它将被替换为对Interval::~Interval
的未定义引用。最好定义函数,或者在他不需要时删除它们!@bdonlan:Interval::~Interval
不是Interval::Interval
。他可能做了未定义ED私有默认构造函数,因此它不能使用,例如“代码>间隔A;将不起作用,而Interval::Interval()
也是。为什么呢?是的,因为它需要实现所有的方法来构建vtable.aaah..你说得对…我刚刚添加了Interval::~Interval(){},它成功了!