2010-07-11 93 views
5

所以我一直在思考PIMPL和堆栈分配。我一直在写图书馆,并决定使用PIMPL来隐藏课程的私人成员。这意味着我会有一个这样的声明PIMPL和堆栈分配

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

这是非常简单的。但随后在构造函数中完成此

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

因此,当有人使用我的图书馆在栈上创建了一个富,他们基本上是做一个堆分配反正。这是在使用PIMPL时必须权衡的折衷?我想在构造函数旁边发布一个警告文件:“警告:这会导致堆分配”或其他。

我的另一个想法是将所有暴露于实现的类作为纯虚拟接口和一大堆静态工厂方法返回智能指针。这也意味着堆分配,但没有技巧。

任何想法或建议?我是否过度体贴使用我的图书馆的程序员?

+1

这样的警告的问题是大量的操作导致堆分配。创建一个'std :: vector'也可以。或者调整一个。权衡隐藏类的内部是多么重要,而避免堆分配的额外表现。 – jalf 2010-07-11 06:51:38

回答

4

这是在使用PIMPL时必须权衡的权衡吗?

有效,是的,虽然有技术,如那些由香草萨特在"The Fast Pimpl Idiom,"讨论了可用于消除或加快堆分配,以更大的复杂性为代价。

我想释放构造函数旁边的警告文档:“警告:这会导致堆分配”或somesuch。

只有在必要时才这样做(即只有当您的用户会对您的班级执行堆分配感到惊讶时)。许多类执行堆分配,包括C++标准库中的许多类(例如所有容器)。

我是否过度体贴使用我的图书馆的程序员?

可能:-)。除非你对班级有很高的性能要求,或者你希望班级的例子经常被创建和销毁,否则我不会太担心。当然,如果你有明显的性能要求,pimpl可能不是一个好的选择。

+0

很酷,谢谢。无论如何,我会看起来像Fast Pimpl,因为它看起来很有趣。 – Anthony 2010-07-11 02:42:31

4

所以当有人使用我的库在堆栈上创建一个Foo时,它们实质上是在做一个堆分配。这是在使用PIMPL时必须权衡的折衷?

是的。

我想释放构造函数旁边的警告文档:“警告:这会导致堆分配”或somesuch。

我会考虑过度激烈的评论:)如果你的课是如此性能的关键,也许你应该避免PIMPL成语。如果你代表一个号码,这可能是值得关注的,值得注意。如果你隐藏了实现一个数据库连接的,不值得评论:)

我的另一个想法是有其暴露于实施为纯虚拟接口和一大堆的静态工厂方法返回的所有类聪明的指针。这也意味着堆分配,但没有技巧。

是的,这对用户来说更加明显,但是可能再也不值得关注自己了。

有什么想法或建议吗?我是否过度体贴使用我的图书馆的程序员?

这是一个折衷,但如果你的班级足够复杂以从pimpl习语中获得真正的收益,那么你可能会认为堆分配是可以的。如果我正在使用你的库,它可能不会涉及我。

+0

很酷,谢谢。我会继续做'我在干什么'。 – Anthony 2010-07-11 02:44:40