从 DLL 中导出前向声明 类
Exporting forward declared classes from a DLL
我想从 DLL 导出 class。它使用 Pimpl 习语,如:
#ifdef THING_EXPORT
#define THING_API __declspec(dllexport)
#else
#define THING_API __declspec(dllimport)
#endif
class thing_impl;
class THING_API thing
{
public:
...
private:
thing_impl* pimpl_;
};
thing_impl
的构造函数或析构函数(或任何方法)在该 DLL 之外将不可用。我是否必须将 THING_API
放在前向声明名称 thing_impl
的前面?
Do I have to put THING_API
in front of the forward declared name thing_impl
?
视情况而定,但考虑到 pimpl 习语的性质,不,您不需要导出它。
您可能会收到有关未导出的警告和错误,these can be silenced 要么针对整个项目,要么将其限制在成员变量的范围内(如下所示);
class thing_impl;
class THING_API thing
{
public:
...
private:
#pragma warning(push)
#pragma warning(disable: 4251)
thing_impl* pimpl_;
#pragma warning(pop)
};
实现中要考虑的其他因素是将"pimpl"实现classthing_impl
声明为private inside thing
class以进一步限制潜在访问权限。
class THING_API thing
{
public:
thing(const thing&);
thing& operator=(const thing&);
thing(thing&&); // if needed
thing& operator=(thing&&); // if needed
~thing();
...
private:
class thing_impl;
#pragma warning(push)
#pragma warning(disable: 4251)
thing_impl* pimpl_;
#pragma warning(pop)
};
需要注意的一件事是当从一个DLL中导出一个class时,整个class都会被导出,所以要确保适当的复制构造函数、复制赋值运算符和析构函数(如上所述)并已实现(如果需要,还可以添加移动函数)。如果它们不存在,编译器将生成它们,并且考虑到使用 pimpl_
成员,它们很可能不正确。为此,您还可以考虑使用 std::shared_ptr
来协助管理 pimpl_
.
我想从 DLL 导出 class。它使用 Pimpl 习语,如:
#ifdef THING_EXPORT
#define THING_API __declspec(dllexport)
#else
#define THING_API __declspec(dllimport)
#endif
class thing_impl;
class THING_API thing
{
public:
...
private:
thing_impl* pimpl_;
};
thing_impl
的构造函数或析构函数(或任何方法)在该 DLL 之外将不可用。我是否必须将 THING_API
放在前向声明名称 thing_impl
的前面?
Do I have to put
THING_API
in front of the forward declared namething_impl
?
视情况而定,但考虑到 pimpl 习语的性质,不,您不需要导出它。
您可能会收到有关未导出的警告和错误,these can be silenced 要么针对整个项目,要么将其限制在成员变量的范围内(如下所示);
class thing_impl;
class THING_API thing
{
public:
...
private:
#pragma warning(push)
#pragma warning(disable: 4251)
thing_impl* pimpl_;
#pragma warning(pop)
};
实现中要考虑的其他因素是将"pimpl"实现classthing_impl
声明为private inside thing
class以进一步限制潜在访问权限。
class THING_API thing
{
public:
thing(const thing&);
thing& operator=(const thing&);
thing(thing&&); // if needed
thing& operator=(thing&&); // if needed
~thing();
...
private:
class thing_impl;
#pragma warning(push)
#pragma warning(disable: 4251)
thing_impl* pimpl_;
#pragma warning(pop)
};
需要注意的一件事是当从一个DLL中导出一个class时,整个class都会被导出,所以要确保适当的复制构造函数、复制赋值运算符和析构函数(如上所述)并已实现(如果需要,还可以添加移动函数)。如果它们不存在,编译器将生成它们,并且考虑到使用 pimpl_
成员,它们很可能不正确。为此,您还可以考虑使用 std::shared_ptr
来协助管理 pimpl_
.