PIMPL习惯用语VS前向声明 [英] PIMPL idiom VS forward declaration

查看:107
本文介绍了PIMPL习惯用语VS前向声明的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经阅读了一些有关PIMPL习惯用法的内容,并且想知道-转发声明依赖类型有什么不同吗?

如果是这样:

  • 什么时候我会更喜欢使用它而不是向前声明?
  • 这两个版本的编译时间是否不同?
  • 其中一个比另一个更具扩展性吗?

具体考虑依赖于Bar的类Foo(应该具有类型Bar的成员).

Foo.h带有前向声明:

class Bar;

class Foo
{
public:
    Foo();

private:
    Bar* _bar;
};

Foo.h与PIMPL:

class Foo
{
    public:
        Foo();

    private:
        /* FooImpl is an incomplete type at this point.
         * Implemented in cpp file and has a member of type Bar.
         */
        class FooImpl;  

        FooImpl* _fooImpl;
}

请忽略原始指针的用法-我只是想提出一个要点.

解决方案

我已经阅读了一些有关PIMPL习惯用法的内容,并且想知道-转发声明依赖类型有什么不同吗?

是的,它们是不同的. PIMPL习惯用语(它具有

我什么时候比起前向声明更喜欢使用[PIMPL]?

这实际上与意图有关-您的代码与抽象有关-照顾好这些抽象,对其进行营养并保护它们,它们将为您提供良好的服务.

问题变成了-哪个更好地代表了您的意图?我敢说FooImpl更好,我感觉到您的意图是向客户端隐藏该类的实现,而该实现更好地表示了该意图(因为客户端无法访问FooImpl).

如果您打算在类Foo之外的代码中的其他地方使用Bar,则该实现会更好,因为这是目的,并且该实现允许您这样做.

这两个版本的编译时间是否不同?

我对此表示怀疑. BarFooImpl的实现在定义它们的翻译单元之外不可见.

其中一个比另一个更具扩展性吗?

不是,不是.从某种通用意义上讲,代码越清晰,人们就越容易扩展它.

I have read a bit about the PIMPL idiom and was wondering - is it any different to forward declaring the dependent type(s)?

If so:

  • When will I prefer using that over a forward declaration?
  • Do these two versions differ in their compilation time?
  • Is one of them more scalable than the other?

Specifically consider a class Foo that is dependent on Bar (should have a member of type Bar).

Foo.h with forward declaration:

class Bar;

class Foo
{
public:
    Foo();

private:
    Bar* _bar;
};

Foo.h with PIMPL:

class Foo
{
    public:
        Foo();

    private:
        /* FooImpl is an incomplete type at this point.
         * Implemented in cpp file and has a member of type Bar.
         */
        class FooImpl;  

        FooImpl* _fooImpl;
}

Please ignore the raw pointer usage - I was just trying to make a point.

解决方案

I have read a bit about the PIMPL idiom and was wondering - is it any different to forward declaring the dependent type(s)?

Yes, they are different. The PIMPL idiom (it has several names) is specifically about hiding the implementation detail from the client code. This could be done for a number of reasons, including (but not limited to);

  • isolating the rebuild when class details change (they are hidden)
  • minimising required or conflicting header inclusions
  • a general build time reduction
  • minimal export requirements (although abstract classes could be used for this purpose as well)
  • easier control over implementation detail that varies over multiple targets or platforms

In essence, the PIMPL offers a technique to "hide" the implementation from the client code - whenever that may be needed.

When will I prefer using [PIMPL] over forward declaration?

This is really about intent - your code is about abstractions - take care of those abstractions, nuture them and protect them, they will serve you well.

The question becomes - which one better represents your intent? I would venture to say that the FooImpl is better, I sense your intent is to hide the implementation of the class from the client and this implementation better represents that intent (since FooImpl is not accessible to the client).

If your intent to is to use Bar elsewhere in the code, outside of the class Foo, then that implementation is better because that is the intent and that implementation allows you to do that.

Do these two versions differ in their compilation time?

I doubt that. The implementation of Bar and FooImpl are not visible outside the translation unit they are defined in.

Is one of them more scalable than the other?

Not really, no. In some generic sense, the clearer code is, the easier people are able to scale it.

这篇关于PIMPL习惯用语VS前向声明的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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