繁体   English   中英

在导出的类中使用std :: unique_ptr

[英]Using std::unique_ptr in an exported class

我在DLL中有一个看起来像这样的类:

#ifdef LIB_EXPORT
#define LIB_API __declspec(dllexport)
#else
#define LIB_API __declspec(dllimport)
#endif

...

class LIB_API MyClass {
public:
  // ...public interface...
private:
 // ...some private fields...
 std::unique_ptr<OtherClass> otherPtr_;
};

现在,我认为这可能是一个问题:如果客户端代码使用的unique_ptr版本略有不同,则MyClass对象的内存布局实际上将与DLL中的代码有所不同。

我真的不想诉诸于Pimpl惯用法来从公共标头中隐藏unique_ptr 我可能会滚动自己的简化版本的unique_ptr (我只需要其功能的子集,例如,我不需要自定义删除器)。 但是,在尝试之前,是否还有其他方法可以解决此问题?

您认为的问题是很实际的,它不仅适用于Standard库类的布局,还适用于您自己的类。 除非您的类满足标准布局规则,否则即使给定完全相同的源代码,也不希望不同的编译器使用相同的内存布局。 答案是完全不应该导出C ++类。


情况#1:如果要用unique_ptr来管理DLL的公共对象的生存期:

从DLL导出工厂函数和删除函数,并将包装器类放在公共头文件中。 包装器完全存在于客户端中,因此仅使用客户端的unique_ptr版本。

__declspec(dllexport)包装类上使用。


情况2:如果DLL内部使用了unique_ptr

应该使用继承而不是pimpl。 公共头文件包含一个基类,该基类具有受保护的构造函数,纯虚拟成员函数并且完全没有数据成员。 同样,不使用__declspec(dllexport) dllexport工厂函数用于创建新实例。 在DLL中,您将从该接口类型继承,派生类添加所有数据成员和函数体。 客户端从未见过任何数据成员,因此您可以自由使用C ++对象,并且所使用的布局是DLL本地的。


这两个方面的副作用是琐碎的成员函数将不会被内联,这可能会对性能产生负面影响。 但是,对每个成员访问都调用DLL是实现解耦的唯一方法。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM