C ++ pimpl避免void *

时间:2016-02-10 05:59:41

标签: c++ c++11 pimpl-idiom

假设我有一个我想要隐藏的库。在该库中,有一个名为“fun”的函数

//Both class1 and class2 are defined in the library I want to hide
class1 fun(class2 P)

我正在为class1和class2创建pimpl。 我应该如何实现“有趣”功能? class1_pimpl和class2_pimpl的代码位于

之下
//class1_pimpl.hpp
class class1_pimpl
{
  public:
    class1_pimpl(int value);
    ~class1_pimpl();

  private:
    class Impl;
    std::unique_ptr<Impl> pimpl_;
};

//class2_pimpl.hpp
class class2_pimpl
{
  public:
    class2_pimpl(int value);
    ~class2_pimpl();

  private:
    class Impl;
    std::unique_ptr<Impl> pimpl_;
};

我只能弄清楚该函数是否只与一个类相关,例如

int fun_simple(class1 c, int i)

我解决fun_simple的方式如下:

//class1_pimpl.cpp
class class1_pimpl::Impl
{
  public:
    Impl(int value)
      : value_ {value}
    {}

    int fun_simple(i)
    {
      return value_ + i;
    }

  private:
     int value_;

};

class1_pimpl::class1_pimpl(int value)
  : pimpl_{new Impl(value)}
{}

class1_pimpl::~class1_pimpl()
{}

int class1_pimpl::fun_simple(int i)
{
  return pimpl_->fun_simple(i);
}

由于

2 个答案:

答案 0 :(得分:0)

您假设C ++中的函数应该是成员函数。从int fun_simple(class1 c, int i) int class1_pimpl::fun_simple(i)的“实施”中可以清楚地看出这一点。没有必要这样做。 C ++具有免费功能。 int fun_simple(class1 c, int i)是一个非常精细的定义。

您想要改变的一件事是int fun_simple(class1 const&c, int i)。这意味着不需要复制该类。反过来,您不需要使用复制构造函数。而 意味着您可能只能向前声明class1;。你甚至不需要pimpl! 相反,在标题中,您只需提供std::unique_ptr<class1> makeClass1(/* your args*)即可。

答案 1 :(得分:0)

在大多数情况下,函数应使用公共构造函数构造返回值。然后,您不需要任何提升访问该类的权限,并委托成员或使其成为第一个成员的朋友。

如果这些类绑在一起使用私有构造函数是可取的,那么您总是可以将该函数作为class2的朋友。

为了避免需要class2_pimpl的定义,在class2中创建一个私有构造函数,它将负责构造并填充它。无论如何,在构造函数中执行它都会更可靠。 / p>

另外,fun_simple确实需要class1的副本吗?如果没有,它应该采用const引用。特别是因为用pimpl复制一个类涉及分配和分配相当慢。