• undefined reference to `vtable


    c++ 编译错误

    undefined reference to vtable
    undefined reference to Abstract_base::~Abstract_base()

    c:/mingw/bin/../lib/gcc/mingw32/9.2.0/../../../../mingw32/bin/ld.exe: C:\Users\ssas0e\AppData\Local\Temp\ccwtXlSL.o:abstract_class.cpp:(.text$_ZN13Abstract_baseC2Ev[__ZN13Abstract_baseC2Ev]+0xa): undefined reference to `vtable for Abstract_base'
    c:/mingw/bin/../lib/gcc/mingw32/9.2.0/../../../../mingw32/bin/ld.exe: C:\Users\ssas0e\AppData\Local\Temp\ccwtXlSL.o:abstract_class.cpp:(.text$_ZN17derived_from_baseC1Ev[__ZN17derived_from_baseC1Ev]+0x4d): undefined reference to `Abstract_base::~Abstract_base()'
    c:/mingw/bin/../lib/gcc/mingw32/9.2.0/../../../../mingw32/bin/ld.exe: C:\Users\ssas0e\AppData\Local\Temp\ccwtXlSL.o:abstract_class.cpp:(.text$_ZN17derived_from_baseD1Ev[__ZN17derived_from_baseD1Ev]+0x3e): undefined reference to `Abstract_base::~Abstract_base()'
    
    • 1
    • 2
    • 3

    错误代码示例子

    #include 
    
    using namespace std;
    
    class Abstract_base
    {
        public:
        virtual ~Abstract_base();
        virtual void interface() const{};
        
    };
    
    class derived_from_base : public Abstract_base
    {
        public:
        derived_from_base()
        {
            cout <<"derived ctor" << endl;
    
        }
    
        ~derived_from_base() override
        {
            cout << "~ derived dtor" << endl;
        }
    
        void interface() const override{}
    
    };
    
    int main()
    {
        derived_from_base b;
        return 1;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35

    分析

    vtable虚函数表,报错说的是 undefined reference to
    就是说,指向这个表的reference是未定义的。
    为什么? 这个表不存在? 还是reference不存在?

    子对象构造的过程

    derived_from_base b 开始构造时候,先构造父类的,然后构造自己的,是一种自上而下的过程。我们看到编译的错误也是先父类出的问题,然后是子类出的问题。

    父类哪里出的问题?
    我们看下父类构造virtual fucntion过程。

    • 每一个class 产生出一堆指向virtual functions的指针,放在表格中。这个表格称为virtual table vtbl
    • 每一个class object被安插一个指针,指向相关的virtual table。通常这个指针被称为vptr. vptr的设定和重置都是由每一个class的constructor 和destructor和copy assignment运算符自动完成的。每个class所关联的type_infor_object(用以支持runtime type identification)也经由virtual table被指出来,通常放在表格的第一个slot.

    国外一个针对此问题更加详细的讨论
    总结下

    • look at your class definition. Find the first non-inline virtual function that is not pure virtual (not “= 0”) and whose definition you provide (not “= default”).

      If there is no such function, try modifying your class so there is one. (Error possibly resolved.)
      See also the answer by Philip Thomas for a caveat.

    • Find the definition for that function. If it is missing, add it! (Error possibly resolved.)

      If the function definition is outside the class definition, then make sure the function definition uses a qualified name, as in ClassName::function_name.

    • Check your link command. If it does not mention the object file with that function’s definition, fix that! (Error possibly resolved.)

    • Repeat steps 2 and 3 for each virtual function, then for each non-virtual function, until the error is resolved. If you’re still stuck, repeat for each static data member.

    回到最初问题

    上述代码的错误,是未定义function,只是声明。所以function pointer应该没产生成功,更别说后面的virtual table了。

  • 相关阅读:
    Go:关于 Channel
    拉线地表位移监测仪SD202 滑坡裂缝监测
    客户分析:必须要找出这5种客户?(BP分析)
    9.22数电(触发器&寄存器&一些电路分析&reg的思考)
    C和指针 第14章 预处理器 14.1 预定义符号
    Java日志 -slf4j、logback、log4j2、springboot中日志
    Java之转换流的详细解析
    文件批量移动自动创建文件夹及生成编号重命名,让整理更轻松
    C#开发的ToLookup接口
    解决kubernetes node节点flannel网卡始终不能添加成功的问题
  • 原文地址:https://blog.csdn.net/tortelee/article/details/127935258