如何在DLL导出的接口中处理析构函数

Fla*_*ire 2 c++ dll destructor pure-virtual dllexport

我正在尝试从DLL导出类。我阅读了此文章:http : //www.codeproject.com/Articles/28969/HowTo-Export-C-classes-from-a-DLL

“成熟”的方法建议使用抽象类,因此我有:

// Header
class IFoo{
public:
    virtual int getBar() = 0;
}

class Foo: public IFoo {...}

DLLEXPORT IFoo* Create();
DLLEXPRT void Free(IFoo* inst);

//DLL cpp
IFoo* Create(){ return new Foo; }
void Free(IFoo* inst){ delete inst; }
Run Code Online (Sandbox Code Playgroud)

让我感到困惑的是:如果我没有虚拟析构函数,则delete inst不会调用Foos析构函数,并且可能会泄漏内存。我应该如何处理?本文没有给出答案。

使用virtual ~IFoo(){}是不可能的,因为这会向IFoo中添加一个实现,该实现会导致问题(在有关内联虚拟函数的文章中对问题的回答中作了解释),并virtual ~IFoo() = 0;因未定义符号上的链接器错误而失败~IFoo

安全的方法是什么?释放/释放功能应如何实现?

Mat*_* M. 5

首先,请注意,该问题特定于Visual Studio对DLL的处理。GCC和Clang都具有稳定的ABI(Itanium ABI),可保证使用不同版本编译的库的兼容性。

现在,如上所述,您在这里面临的问题是ABI不稳定,但是ABI的某些部分是稳定的(虚拟表布局),否则提出的策略将根本行不通。

因此,仅使用virtual析构函数即可。由于通过虚拟表进行的调用不会出现名称修改问题。

另外,请注意,在现代C ++中,返回原始指针是不行的,但是名称修改会阻止使用智能指针。

// Foo.h
class Foo {
public:
    virtual int get() = 0;
    virtual ~Foo();

protected:
    Foo() = default;
    Foo(Foo&&) = default;
    Foo(Foo const&) = default;
    Foo& operator=(Foo) = default;
};

// WARNING: immediately capture this Foo* in a smart pointer,
//          or suffer from memory leak (and worse).
Foo* createFoo(); // factory behind

// Foo.cpp
Foo::~Foo() {} // not inline
Run Code Online (Sandbox Code Playgroud)