PIMPL成语澄清

PIMPL idiom clarification

本文关键字:成语 PIMPL      更新时间:2023-10-16

尝试从我决定使用的标头文件中删除所有实现详细信息时,然后尝试PIMPL IDIOM。大多数示例,例如cppreference,我已经看到使用间接水平,除了封装以外,我无法理解的原因。这些示例总是带有这种风味。

典型

//A.hpp
class A
{
public:
    A(int);
    //More non-static class methods
    void set(int);
private:
    struct a_impl;
    std::unique_ptr<struct a_impl> pimpl;
};
//A.cpp
struct A::a_impl
{
private:
    int i;
public:
    a_impl(int i) : i{i}{}
    //More non-static implementation class methods
    void set(int i) {this->i = i;}
};
A::A(int i) : std::make_unique<struct a_impl>(i) {}
A::set(int i) {pimpl->set(i);}  //????
A:://More indirect calls to non-static member functions through pointer

在某些方面,我开始想知道为什么我们要谈论实现,为什么需要所有这些复杂性和间接程度。为什么没有所有这些间接呼叫的情况下最简单的东西。

为什么不

    //A.hpp
class A
{
public:
    A(int);
    //.....
    void set(int);
private:
    struct a_impl;
    std::unique_ptr<struct a_impl> pimpl;
};
//A.cpp
struct A::a_impl
{
    int i;
}
A::A(int i) : std::make_unique<struct a_impl>() { pimpl->i = i; }
A::set(int i) { pimpl->i = i; } //!!!!

我想澄清的:

1-所有这些样本仅出于教育和良好的封装实践而呈现?

2- 除了问题1?

3-或我推出的替代方案不是pimpl习惯吗?

您自己的方法,而与之比较的方法仅是习惯的两种不同风味。Herb Sutter在GOTW#100中列出了它们,等等:

班级应该进入IMPH对象?一些潜力 选项包括:

  • 将所有私人数据(但不是功能)放入Impl;
  • 将所有私人成员置于Impl;
  • 将所有私人和受保护的成员置于Impl;
  • 将所有私人非虚拟成员置于Impl;
  • 将所有内容都放入sphand中,并将公共类本身写成仅作为公共接口,每个界面都作为简单的转发功能实现 (手柄/身体变体)。

每个人都有自己的强大和弱点。对于您学习的情况,您的方法似乎更好。对于其他情况,具有行为的PIMPL,而不仅仅是状态更合适。实际上没有一个尺寸适合所有尺寸。