在Class中声明但未定义的虚方法

时间:2014-04-01 04:45:42

标签: c++ virtual linker-errors defined

我的目的是找到调用某些函数的所有地方。 所以我从中定义了新类的内在性,并使函数不可访问。 但我没有定义方法,我收到了链接错误。

以下是代码:

A.hpp

#ifndef _A_HPP
#define _A_HPP
class _declspec(dllexport) A 
{
public:
    virtual void f1();
};
class _declspec(dllexport) B: public A 
{
private:
    void f1();
};
#endif

A.cpp

#include "A.hpp"
 void A::f1(){}

program.cpp

#include "A.hpp"

int main(void )
{
    A a;
    a.f1();
    return 0;
}
永远不会调用

B::f1(),但我仍然有链接错误。 但如果您删除_declspec(dllexport),则构建正常。

1 个答案:

答案 0 :(得分:1)

该函数由A类的虚函数表引用。

http://en.wikipedia.org/wiki/Virtual_method_table

您不能拥有未定义的虚拟功能(除了纯虚函数)。必须定义它们,以便定义虚拟表。

将函数设为私有也是徒劳的,因为简单地调用(& A).f1()将调用B :: f1()。


编辑以澄清您的编辑,编译以下内容但没有优化,

struct Foo { virtual void foo(); };
struct Goo : public Foo { void foo() {} };

int main()
{
        Goo f;
        return 0;
}

导致链接器错误(使用GCC),

undefined reference to `typeinfo for Foo'

这是预期的。在移除导出的情况下,MSVC可能会作弊。它可以看到整个类及其所有用途,并且不会生成虚拟表。它优化了它。它知道您没有在外部代码中使用该虚拟表,所以它不会打扰它。

如果我按照完全相同的原因打开优化编译,也没有错误。