C++痘痘避免空白*

C++ pimpl avoiding void*

本文关键字:空白 C++      更新时间:2023-10-16

>假设我有一个想要隐藏的库。在该库中,有一个名为"fun"的功能

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

我现在正在为 Class 1 和 Class 2 创建痘痘。我应该如何实现"有趣"功能?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);
}

谢谢

你假设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*)

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

如果类捆绑在一起以至于最好使用私有构造函数,则始终可以将该函数作为class2的朋友。

为了避免需要class2_pimpl的定义,请在class2中创建一个私有构造函数,负责构造和填充它。无论哪种方式,在构造函数中执行此操作都会更可靠。

附带说明一下,fun_simple真的需要class1的副本吗?如果没有,它应该采用常量引用。特别是因为复制带有 pimpl 的类涉及分配并且分配相当慢。