代码之家  ›  专栏  ›  技术社区  ›  Anthony Atmaram

PIMPL和堆栈分配

  •  5
  • Anthony Atmaram  · 技术社区  · 14 年前

    所以我一直在考虑PIMPL和堆栈分配。我一直在编写一个库,并决定使用pimpl来隐藏该类的私有成员。这意味着我会让一个类像这样声明

    class Foo {
    private:
        class Handle;
        std::tr1::shared_ptr<Handle> handle;
    public:
        Foo();
    };
    

    它很直。但是在构造器中,您可以这样做

    Foo::Foo() : handle(new Handle()) {}
    

    所以当有人使用我的库在堆栈上创建一个foo时,他们实际上正在做一个堆分配。在使用PIMPL时,这是您必须面对的权衡吗?我考虑发布文档,在构造函数旁边有一个警告:“警告:这会导致堆分配”或其他类似的情况。

    我的另一个想法是将所有暴露在实现中的类作为纯虚拟接口,以及返回智能指针的一组静态工厂方法。这也意味着堆分配,但没有什么诀窍。

    有什么想法或建议吗?我对使用我的库的程序员是否过于体贴?

    2 回复  |  直到 14 年前
        1
  •  4
  •   James McNellis    14 年前

    在使用PIMPL时,这是您必须面对的权衡吗?

    实际上,是的,尽管有一些技术,例如 "The Fast Pimpl Idiom," 这可以用来消除或加速堆分配,代价是增加复杂性。

    我考虑发布文档,在构造函数旁边有一个警告:“警告:这会导致堆分配”或其他类似的情况。

    仅当需要这样做时(即,仅当您的用户对您的类执行了堆分配这一事实感到惊讶时)。许多类执行堆分配,包括C++标准库中的许多(例如所有容器)。

    我对使用我的库的程序员是否过于体贴?

    可能:-)除非您对类有很高的性能要求,或者您希望类的实例被频繁地创建和销毁,否则我不会太担心它。当然,如果您确实有重要的性能需求,那么PIMPL可能不是一个好的选择。

        2
  •  4
  •   Stephen    14 年前

    所以当有人使用我的库在堆栈上创建一个foo时,他们实际上正在做一个堆分配。在使用PIMPL时,这是您必须面对的权衡吗?

    是的。

    我考虑发布文档,在构造函数旁边有一个警告:“警告:这会导致堆分配”或其他类似的情况。

    我会认为过于激进的评论:)如果你的类对性能如此关键,也许你应该避免使用pimpl习惯用法。如果你代表的是一个数字,这可能是有关的,值得注意。如果您正在隐藏数据库连接的实现,则不值得注释:)

    我的另一个想法是将所有暴露在实现中的类作为纯虚拟接口,以及返回智能指针的一组静态工厂方法。这也意味着堆分配,但没有什么诀窍。

    是的,这对用户来说更明显一点,但可能同样不值得为自己担心。

    有什么想法或建议吗?我对使用我的库的程序员是否过于体贴?

    这是一种权衡,但是如果类足够复杂,能够真正从PIMPL习语中获益,那么您可能可以假定堆分配是正常的。如果我使用你的图书馆,我可能不会担心。

    推荐文章