Search code examples
c++linker-errorsdestructordllexport

Virtual destructor makes it necessary to export the interface on VS2017


I have a C++ interface, let's call it IX with a few methods:

class IX
{
public:
   virtual void foo() = 0;
   virtual void bar() = 0;
}

this interface is located inside a library (dll), but considering the fact that it includes no implementation, it has not been exported.

But, If I want to add a virtual destructor to this interface, like below, then the VS2017 linker complains about the implementation of the destructor that cannot be found:

class IX
{
public:
   virtual ~IX() = 0;
   virtual void foo() = 0;
   virtual void bar() = 0;
}

The linker error:

Error   LNK2019 unresolved external symbol "public: virtual __cdecl IX::~IX(void)" (??1IX@@UEAA@XZ) referenced in function "public: virtual __cdecl B::~B(void)" (??1B@@UEAA@XZ)    test_project

One solution could be to export the interface (and potentially put =default implementation for the dtor). But my Q is why adding a virtual destructor can lead to such kind of linker error?


Solution

  • Making something pure virtual doesn't mean it doesn't have an implementation. Its totally legal (and sometimes useful) to have an implementation of a pure virtual function.

    In the case of foo() = 0; you dont explicitly call IX::foo() anywhere, so not having an implementation is ok. It cant be implicitly called as it'll always be overridden.

    Destructors are different. They will always be implicitly called by the parents destructor in a chain. So you need an implementation of the destructor even if its pure virtual.