【问题标题】:PIMPL: Exporting classes with single STL member (std::unique_ptr)PIMPL:导出具有单个 STL 成员的类 (std::unique_ptr)
【发布时间】:2015-04-15 05:18:03
【问题描述】:

假设我有一个类X,私有实现Ximpl

//Proj.h

#ifdef PROJ_EXPORTS
#define PROJ_API __declspec(dllexport)
#else
#define PROJ_API __declspec(dllimport)
#endif


//X.h

class PROJ_API X
{
  void foo();
  //..
private:
  class Ximpl;
  std::unique_ptr<Ximpl> x_impl;
}

这很好用,但会产生警告:

Compiler Warning (level 1) C4251:

警告 C4251: 'X::Ximpl' : 类 'std::unique_ptr>' 需要有 'X::Ximpl' 类的客户端使用的 dll 接口

我已尝试遵循建议的 MSDN 文章,但是 1)。它没有用。 2)我不清楚解决方案(解决方法)

关于如何摆脱这些警告的任何建议/解释(#pragma disable's 不是一个选项 :))。

为什么是 1 级警告?

注意:事实证明,如果Ximpl 未在X 范围内声明,则可以在Ximpl 的前向声明后导出unique_ptr&lt;Ximpl&gt;,但如果它在Xs 范围内,那么它是一个嵌套类,因此不能前向声明..

但是,对于模板类,即使是上述解决方案(具有非嵌套的 impl 类),似乎也失败了:

//X.h

template<typename T>
class PROJ_API X
{
  T foo();
  //..
private:
  class Ximpl;
  std::unique_ptr<Ximpl> x_impl;
}

【问题讨论】:

  • 你不是说std::unique_ptr&lt;Ximpl&gt; x_impl;吗?
  • @Pradhan 是的,你是对的,已编辑。谢谢!
  • 我假设在class 之后和X 之前存在直接或宏__declspec(dllexport);正确吗?
  • @WhozCraig - 对,已编辑。以及 .cpp 文件中Ximpl 的声明/定义
  • 可能的解决方案是从 X 类中删除 PROJ_API 说明符并将其添加到各个 X 方法中。

标签: c++ visual-c++ stl unique-ptr pimpl-idiom


【解决方案1】:

确保您的 X 类导出并声明非内联析构函数。否则编译器会隐式声明内联析构函数,它需要知道一些关于 Ximpl 的信息才能调用它的析构函数。并且使用内联析构函数,X 的用户还需要知道如何销毁 std::unique_ptr,这会导致警告。

您可以通过检查当 X 被删除时没有调用 ~Ximpl() 来确认这一点,除非您导出非内联 ~X()。

【讨论】:

  • - 谢谢你的好建议,这很有意义。但是,我在每个类中都实现了非内联构造函数。但是,如果我不导出(如 MSDN 文章中所述)unique_ptr&lt;Ximpl&gt;,它不会消除警告。在模板类的情况下,我什至无法导出 STL 成员(它现在是 2 嵌套模板)。请注意,可以导出实例化的模板类,但不能导出通用 X&lt;T&gt;
  • 你的意思是你有非内联析构函数?
  • 是的,我的意思是“析构函数”,而不是“构造函数”。但是,我两者都有
猜你喜欢
  • 2015-07-16
  • 2016-08-18
  • 2022-01-12
  • 1970-01-01
  • 2015-11-12
  • 1970-01-01
  • 2015-05-01
  • 2017-01-15
  • 2014-08-30
相关资源
最近更新 更多