静态库中的虚函数

时间:2013-05-27 20:47:57

标签: c++ static-linking vtable

当我有一个在foo

中定义的抽象基类libX.a
class foo {
    virtual void bar() = 0;
};

...以及foo_impl

中定义的派生类libY.a
class foo_impl : public foo {
    void bar() { /* do something */ }
};

...并使用这两个库链接程序-lX -lY

int main() {
    foo* my_foo = receive_a_foo_from_somewhere();
    my_foo->bar();
}

然后

  • 如何强制链接器实际链接引用foo_impl::bar()
  • 的符号 正确链接时,
  • objdump -t program列出foo_impl::bar()吗?

编辑:澄清一下,我正在使用linux与gcc或clang

编辑2:错过了virtual的{​​{1}}

编辑4:我为缺少清晰度而道歉。问题应该是“如何强制链接器在可执行文件中实际包含bar(),以便在运行时解析它?”

2 个答案:

答案 0 :(得分:0)

由于bar方法被定义为虚拟,因此不需要静态链接。链接将在运行时根据* my_foo引用的对象类型动态完成。无论是在libX.a还是libY.a中定义的。

您的问题是如何强制链接器链接引用foo_impl :: bar()的符号?

您无法强制链接器链接到特定实现。链接将根据您从receive_a_foo_from_somewhere()获得的对象地址发生。

显然,实现应该与你的exe相关联。如果它不可用它肯定会失败。但是你不能强迫链接器链接特定的实现,

答案 1 :(得分:0)

似乎至少有两种方法可以让链接器在可执行文件中包含foo_impl::bar()功能:

  1. 使用gcc,可以使用-Wl,--whole-archive链接整个静态库 - 无论如何。
  2. 正如Obvlious船长所指出的,当程序中使用foo_impl时,它的虚函数被标记为已被使用,因此包含在可执行文件中。这也可能是一个无用的静态虚拟 foo_impl对象。