PIMPL:使用单个STL成员导出类(std :: unique_ptr)

时间:2015-02-14 02:50:54

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

假设我有一个私有实施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&GT;'需要有   dll-interface由'X :: Ximpl'类的客户端使用

我试图按照建议的MSDN文章,但1)。它不起作用。 2)我不清楚解决方案(解决方法)

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

为什么会出现1级警告?

注意:如果在Ximpl范围内未声明X,则可以在unique_ptr<Ximpl>的前向声明后导出Ximpl,但如果它位于X范围内,那么它是一个嵌套类,因此无法向前声明..

但是,对于模板类甚至上面的解决方案(具有非嵌套的impl类),似乎都失败了:

//X.h

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

1 个答案:

答案 0 :(得分:2)

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

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