实践中的Pimpl成语 [英] The Pimpl Idiom in practice

查看:156
本文介绍了实践中的Pimpl成语的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对于关于 pimpl成语的问题,我有几个问题,但我更好奇它在实践中被利用的频率。

There have been a few questions on SO about the pimpl idiom, but I'm more curious about how often it is leveraged in practice.

我知道在性能和封装之间有一些权衡,以及由于额外的重定向而引起的一些调试烦恼。

I understand there are some trade-offs between performance and encapsulation, plus some debugging annoyances due to the extra redirection.

这是应该采用每班,还是全有或全无?这是最好的做法还是个人喜好?

With that, is this something that should be adopted on a per-class, or an all-or-nothing basis? Is this a best-practice or personal preference?

我意识到这有些主观,所以让我列出我的首要任务:

I realize that's somewhat subjective, so let me list my top priorities:


  • 代码清晰

  • 代码可维护性

  • 性能

我总是假设我需要在某个时间将我的代码公开为一个库,所以这也是一个考虑。

I always assume that I will need to expose my code as a library at some point, so that's also a consideration.

EDIT:完成同样操作的任何其他选项都是欢迎的建议。

Any other options to accomplish the same thing would be welcome suggestions.

推荐答案

说,无论你是按类还是以全有或无关为基础,取决于你为什么首先去pimpl成语。在构建库时,我的原因是以下之一:

I'd say that whether you do it per-class or on an all-or-nothing basis depends on why you go for the pimpl idiom in the first place. My reasons, when building a library, have been one of the following:


  • 希望隐藏实现以避免泄露信息它不是FOSS项目:)

  • 希望隐藏实现,以使客户端代码更少依赖。如果你构建一个共享库(DLL),你可以改变你的pimpl类,甚至不需要重新编译应用程序。

  • 希望减少使用库编译类所需的时间。 li>
  • 希望修复命名空间冲突(或类似问题)。

全有或全无的方法。在第一种情况下,你只是想隐藏你想隐藏的内容,而在第二种情况下,你可能已经足够这样做,你希望改变的类。同样对于第三和第四个原因,隐藏非平凡成员只有受益,而这些成员又需要额外的头(例如,第三方库,甚至是STL)。

None of these reasons prompts for the all-or-nothing approach. In the first one, you only pimplize what you want to hide, whereas in the second case it's probably enough to do so for classes which you expect to change. Also for the third and fourth reason there's only benefit from hiding non-trivial members that in turn require extra headers (e.g., of a third-party library, or even STL).

在任何情况下,我的观点是,我通常不会发现这样太有用:

In any case, my point is that I wouldn't typically find something like this too useful:

class Point {
  public:      
    Point(double x, double y);
    Point(const Point& src);
    ~Point();
    Point& operator= (const Point& rhs);

    void setX(double x);
    void setY(double y);
    double getX() const;
    double getY() const;

  private:
    class PointImpl;
    PointImpl* pimpl;
}

在这种情况下,权衡开始命中你,因为指针需要被解引用,并且方法不能被内联。但是,如果你只是为非平凡的类,那么轻微的开销通常可以容忍,没有任何问题。

In this kind of a case, the tradeoff starts to hit you because the pointer needs to be dereferenced, and the methods cannot be inlined. However, if you do it only for non-trivial classes then the slight overhead can typically be tolerated without any problems.

这篇关于实践中的Pimpl成语的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆