已实现的父方法的共享库中没有符号

No symbol in shared library of implemented parent method

我有一个 class AbsAlgorithm,它有 3 个虚拟方法:

class AbsAlgorithm
{
public:
    //..... other methods
    virtual void run() = 0;
    virtual bool init(TestCase&) = 0;
    virtual bool done() = 0;
};

我创建了一个静态库,libAlgatorc.a,包含这个 class。

我还有 class SortingAbsAlgorithm,它继承自 AbsAlgorithm 并覆盖方法 runinitdone

class SortingAbsAlgorithm : public AbsAlgorithm
{
public:
    void run()
    {
        execute(...);
    }

    bool done()
    {
        return result;
    }
}

当我创建包含此 class(以及其他一些 classes)的共享库时,我没有 SortingAbsAlgorithm::runSortingAbsAlgorithm::initSortingAbsAlgorithm::done 在共享库中。为什么?

我这样创建共享库:

g++ -std=gnu++11 -fPIC SortingAbsAlgorithm.cpp SortingTestSetIterator.cpp SortingTestCase.cpp  -shared -o libProject.so -Wl,--whole-archive -lAlgatorc -Wl,--no-whole-archive

您不会在基 class 中看到纯虚函数的任何符号,除非您为它们编写定义,因为编译器不可能为不存在的定义输出任何符号。

您也不会在派生 class 中看到覆盖的任何定义,除非您调用它们,并且可能只有在您调用它们并在没有优化的情况下进行编译时才会看到。

这是因为它们被定义为内联函数(因为您在 class 主体中定义了它们),因此根据 C++ 标准中的 [dcl.fct.spec]/4,编译器知道任何其他目标文件中这些函数的其他调用者也可以看到函数定义,因此编译时不需要发出外部符号 SortingAbsAlgorithm.cpp.

如果要确保编译器输出这些函数的定义,请不要将它们定义为内联函数。或者,如果库中的代码构建了 SortingAbsAlgorithm 的实例,这也将确保库包含虚函数的符号(但不包含库中未调用的任何其他内联函数)。