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;将不起作用,而间隔A(1,2)将重新定义“因为C++将VTE粘贴到第一个函数”。不,C++没有指定生成VTAL的时间或地点,或者甚至根本不使用VTABLE实现虚拟调度。您正在描述一个特定编译器的行为;其他编译器可能表现不同,因此用声明顺序来掩盖错误的游戏不是可移植的。efault构造函数
Interval::Interval()
也是。为什么呢?是的,因为它需要实现所有的方法来构建vtable.aaah..你说得对…我刚刚添加了Interval::~Interval(){},它成功了!