我已经阅读了一些关于 PIMPL 习惯用法的内容并且想知道 - 转发声明依赖类型有什么不同吗?
如果是这样的话:
特别考虑一个Foo依赖于Bar(应该有一个 type 成员)的类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 提供了一种技术,可以在需要时从客户端代码“隐藏”实现。
我什么时候更喜欢使用 [PIMPL] 而不是前向声明?
这真的是关于意图——你的代码是关于抽象的——照顾这些抽象,培养它们并保护它们,它们会很好地为你服务。
问题变成了 - 哪一个更能代表您的意图?我敢说FooImpl更好,我感觉你的意图是向客户端隐藏类的实现,而这个实现更好地代表了这个意图(因为FooImpl客户端无法访问)。
如果您的意图是Bar在代码中的其他地方使用,在 class 之外Foo,那么该实现会更好,因为这就是意图,并且该实现允许您这样做。
这两个版本的编译时间不同吗?
我不信。的实施Bar和FooImpl不可见之外,只在定义翻译单元。
其中一个比另一个更具可扩展性吗?
不是真的,不是。从某种意义上说,代码越清晰,人们就越容易扩展它。