C++共享库:纯虚函数不会导致链接错误

C++ shared library: Pure virtual function does not cause link error

本文关键字:链接 错误 函数 共享 C++      更新时间:2023-10-16

我一直在努力理解为什么我可以在我正在使用的库中尚未实现的头文件中创建一个纯虚拟函数,并且这不会导致链接甚至运行时故障。以上可能有点不精确,但这里有一些代码来支持它。

下面是一个接口定义:

class A
{
public:
    static A* Create();
    virtual ~A() {}
    virtual status_t start() = 0;
    virtual status_t stop() = 0;
};

我有一个C++共享库,其中包含一个实现"AImpl"+ A::Create()函数(见下文):

A* A::Create {return new AImpl;}
class AImpl : public A
{
public:
    A() {}
    virtual ~A() {}
    virtual status_t start() {}
    virtual status_t stop()  {}
};

我构建共享库 - 没问题。现在我在类 A 的头文件中添加了另一个纯虚函数:

class A
    {
    public:
        static A* Create();
        virtual ~A() {}
        virtual status_t start() = 0;
        virtual status_t stop() = 0;
        virtual status_t write() = 0;
    };

我创建了一个使用它的测试应用程序:

void main()
{
    A* a = A::Create();
    a->start();
    a->stop();
    a->write();
}

现在我明白上面的编译,但我认为它会失败链接,因为共享库中没有 write() 调用的实现。即使在运行时,也不会发生崩溃或任何事情。似乎跳过了写入调用。任何人都可以帮助解释 - 将不胜感激:-)

谢谢 - 很抱歉这个冗长的问题,我很难用"单行"解释确切的问题..

纯虚函数在链接过程中永远不会导致任何失败。相反,如果您尝试实例化抽象类型的对象,纯虚函数将导致编译错误。

提醒 - 抽象类型是具有(直接或间接通过继承)至少一个未被覆盖的纯虚函数的类型。

发生的事情是共享库是用A类的一个版本构建的,而可执行二进制文件是用不同的版本构建的。此时,你违反了一个定义规则,编译器可以自由地执行任何操作,包括成功编译和链接代码。在这种情况下,不需要编译器诊断。

如果以前已生成解决方案,则可能会编译或生成。这意味着它使用的是旧目标代码。尝试对解决方案进行干净生成,然后重新生成它。清洁溶液后。然后尝试编译继承的类。另一件可能值得关注的事情是,您已将继承的类声明为:

类 AImpl : A { ... };

我对此的问题是AImpl是如何从A继承的?您打算继承publicprotected还是private继承?

编辑

如果您将其作为库链接到,并且当前解决方案未显示任何编译、生成、链接错误;这是因为您当前的解决方案使用的是已构建的旧libdll。如果返回到库解决方案并执行干净生成,则不应对其进行编译,因此将没有新版本的库可以链接到。