使用指针隐藏实现(Pimpl idiom)

eme*_*esx 11 c++ dependencies pimpl-idiom

是否可能,以实现以下目标:

x.hpp - 许多其他类都包含此文件

class x_impl; //forward declare
class x {
    public:
        //methods...
    private:
        x_impl* impl_;
};
Run Code Online (Sandbox Code Playgroud)

x.cpp - 实现

#include <conrete_x>
typedef concrete_x x_impl;    //obviously this doesn't work
//implementation of methods...
Run Code Online (Sandbox Code Playgroud)

所以基本上,我希望用户包含文件x.hpp,但不知道conrete_x.hpp标头.

由于我concrete_x只能通过指针使用并且它只显示为私有数据成员,因此前向声明应该足以让编译器知道准备多少空间.它看起来很像着名的"pimpl成语".

你能帮帮我吗?

PS.我不想使用它void*并将其投射..

Mat*_* M. 9

实际上,甚至可以完全隐藏用户:

// Foo.hpp
class Foo {
public:

    //...

private:
    struct Impl;
    Impl* _impl;
};

// Foo.cpp
struct Foo::Impl {
    // stuff
};
Run Code Online (Sandbox Code Playgroud)

我想提醒你的是:

  • 你需要写一个合适的析构函数
  • 因此,您还需要一个适当的复制构造函数,复制赋值运算符,移动构造函数和移动赋值运算符

有一些方法可以自动化PIMPL,代价是一些黑魔法(类似于什么std::shared_ptr).


Bar*_*nau 5

作为@Angew答案的替代方案,如果concrete_x不应该让x类用户知道该名称,你可以这样做:

x.hpp中

class x_impl;
class x {
  public:
    x();
    ~x();
    //methods...
  private:
    x_impl* impl_;
};
Run Code Online (Sandbox Code Playgroud)

x.cpp中

#include <concrete_x>
class x_impl : public concrete_x { };

x:x() : impl_(new x_impl) {}
x:~x() { delete impl_; }
Run Code Online (Sandbox Code Playgroud)