简体   繁体   中英

C++ pimpl avoiding void*

Assume I have a library that I want to hide. In that library, there is a function called "fun"

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

I am creating pimpl for class1 and class2 now. How should I implement the function "fun"? The code for class1_pimpl and class2_pimpl is below

//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_;
};

I can only figure out if the function is only related to one class, such as

int fun_simple(class1 c, int i)

The way I solve the fun_simple is like below:

//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);
}

Thanks

You're assuming that functions in C++ should be member functions. That's clear from your "implementation" of int fun_simple(class1 c, int i) as int class1_pimpl::fun_simple(i) . There's no need for that. C++ has free functions. int fun_simple(class1 c, int i) is a perfectly fine definition as-is.

One thing you do want to change is int fun_simple(class1 const&c, int i) . This means the class doesn't need to be copied. In turn, you don't need to have the copy constructor available. And that means that you might be able to just forward-declare class1; . You don't even need a pimpl for this! Instead, in your header you just provide a std::unique_ptr<class1> makeClass1(/* your args*) .

In most cases, the function should construct the return value using a public constructor. Then you don't need any elevated access to that class and either delegate to member or make it a friend of the first one.

If the classes are so tied together that using a private constructor is preferable, you can always make the function a friend of class2 .

To avoid needing the definition of class2_pimpl , create a private constructor in class2 that will take care of constructing it and filling it in. Doing it in a constructor will be more reliable either way.

On a side note, does fun_simple really need a copy of class1 ? If not, it should be taking a const reference. Especially since copying a class with pimpl involves allocation and allocations are rather slow.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM