C++ pimpl избегая пустоты *

Предположим, у меня есть библиотека, которую я хочу скрыть. В этой библиотеке есть функция, которая называется "весело"

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

Я сейчас создаю pimpl для class1 и class2.Как мне реализовать функцию "веселье"? Код для 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 ответа

Вы предполагаете, что функции в 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 предполагает выделение, а выделение происходит довольно медленно.

Другие вопросы по тегам