代码之家  ›  专栏  ›  技术社区  ›  golobitch

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

  •  0
  • golobitch  · 技术社区  · 9 年前

    我有一节课 AbsAlgorithm 它有3种虚拟方法:

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

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

    我也有课 SortingAbsAlgorithm ,继承自 Abs算法 并重写方法 run , init done .

    class SortingAbsAlgorithm : public AbsAlgorithm
    {
    public:
        void run()
        {
            execute(...);
        }
    
        bool done()
        {
            return result;
        }
    }
    

    当我创建包含这个类(和一些其他类)的共享库时 SortingAbsAlgorithm::run , SortingAbsAlgorithm::init SortingAbsAlgorithm::done 在共享库中。为什么?

    我这样创建共享库:

    g++ -std=gnu++11 -fPIC SortingAbsAlgorithm.cpp SortingTestSetIterator.cpp SortingTestCase.cpp  -shared -o libProject.so -Wl,--whole-archive -lAlgatorc -Wl,--no-whole-archive
    
    1 回复  |  直到 9 年前
        1
  •  2
  •   Jonathan Wakely    9 年前

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

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

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

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