如何查找类的未定义虚函数

时间:2010-09-07 11:06:29

标签: c++ oop

我将游戏从windows移植到mac。

在这里,我遇到了一堆链接器错误。所有错误类似于

  

未定义的符号“Baseclass的typeinfo”,引用自:Subclass Subclass.o or的typeinfo“从_ZTVNAclass引用的Aclass的vtable:`

我知道这个问题是因为缺少虚函数的定义。它的大项目很难跟踪未定义的虚函数。是他们以任何方式快速识别未定义的虚函数。

为什么编译器无法识别未定义的虚函数并提供有意义的消息而不是隐藏的vtable消息。

最小例子: -

class Foo
{  
public:  
  virtual ~Foo(){};  
  virtual void  someMethod();  
};

int main()
{
    Foo  foo;
    return 0;
}

g ++版本4.2.1(Apple Inc. build 5664)说: -

Undefined symbols:  
  "vtable for Foo", referenced from:  
      Foo::Foo()   in ccj8yYI2.o  
ld: symbol(s) not found  
collect2: ld returned 1 exit status  

3 个答案:

答案 0 :(得分:2)

我相信这两个错误意味着该类具有虚函数,但没有非内联虚函数(如果您来自Java背景,则很容易)。当GCC在类中发出第一个非内联虚函数时,它会发出vtable和(我相信)typeinfo。如果内联所有虚函数,则不会生成这些位。

您需要将内联虚拟功能移动到源文件并使其成为非内联。析构函数通常是一个很好的候选者。

编辑:我想我误解了你的问题。如何临时使您的虚拟函数非虚拟化,以便链接器为该确切的函数而不是vtable发出缺少的符号?你显然必须记得以后再刷新它们。

EDIT2: 当我尝试编译它时,我得到了描述性错误。你能粘贴一个没有的最小例子吗?

class Foo
{
public:
    virtual ~Foo();
};

int main()
{
    Foo foo;

    return 0;
}

输出:

Undefined                       first referenced
 symbol                             in file
Foo::~Foo()                         /var/tmp//cc4C2j6B.o
vtable for Foo                      /var/tmp//cc4C2j6B.o
ld: fatal: Symbol referencing errors. No output written to a.out
collect2: ld returned 1 exit status

答案 1 :(得分:1)

我遇到过类似的问题。最后我暂时使用了clang而不是gcc,它提供了更好的错误信息:

code.cpp:103:20: fatal error: allocating an object of abstract class type 'MyClass'
    instance = new MyClass();
                   ^
code.h:766:16: note: unimplemented pure virtual method 'ForgottenVirtualMethod' in 'MyClass'
  virtual void ForgottenVirtualMethod(int x, int y) = 0;
               ^
1 error generated.

答案 2 :(得分:0)

当类BaseClass不是多态时,通常会出现第一个问题。确保它至少有一个虚函数(虚拟析构函数可以正常运行)。

对于AClass的问题,请确保有一个.cpp文件,其中定义了Aclass的虚拟方法。确保它们未在头文件中定义。可悲的是,至少据我所知,不会有任何神奇的工具。