PIMPL 和堆栈分配
所以我一直在思考 PIMPL 和堆栈分配。我一直在编写一个库,并决定使用 PIMPL 来隐藏类的私有成员。这意味着我将有一个这样声明的类,
class Foo {
private:
class Handle;
std::tr1::shared_ptr<Handle> handle;
public:
Foo();
};
这非常简单。但是然后在构造函数中执行此操作
Foo::Foo() : handle(new Handle()) {}
因此,当有人使用我的库在堆栈上创建 Foo 时,他们本质上无论如何都在进行堆分配。这是您在使用 PIMPL 时必须忍受的权衡吗?我考虑发布文档,并在构造函数旁边添加警告:“警告:这会导致堆分配”或类似内容。
我的另一个想法是让所有暴露给实现的类作为纯虚拟接口和一大堆返回智能指针的静态工厂方法。这也意味着堆分配,但没有什么技巧。
有什么想法或建议吗?我是否过于考虑使用我的库的程序员?
So I've been thinking about PIMPL and stack allocation. I've been writing a library and decided to use PIMPL to hide the private member of the class. That means I would have a class declared like this
class Foo {
private:
class Handle;
std::tr1::shared_ptr<Handle> handle;
public:
Foo();
};
It's pretty straight forward. But then in the constructor you do this
Foo::Foo() : handle(new Handle()) {}
So when someone using my library creates a Foo on the stack, they are essentially doing a heap allocation anyway. Is this the trade-off you have to live with when using PIMPL? I thought of releasing the documentation with a warning next to constructors: "WARNING: This results in a heap allocation" or somesuch.
My other thought was to have all classes which are exposed to the implementation as pure virtual interfaces and a whole bunch of static factory methods returning smart pointers. This also means heap allocation but there is no trick to it.
Any thoughts or suggestions? Am I being overly-considerate of programmers using my library?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
实际上,是的,尽管有一些技术,例如 Herb Sutter 在 “The Fast Pimpl Idiom”中讨论的技术,” 可用于消除或加速堆分配,但代价是更加复杂。
仅当有必要时才这样做(即,仅当您的用户会对您的类执行堆分配这一事实感到惊讶时)。许多类执行堆分配,包括 C++ 标准库中的许多类(例如,所有容器)。
可能:-)。除非您对类有很高的性能要求,或者您希望类的实例被非常频繁地创建和销毁,否则我不会太担心。当然,如果你确实有显着的性能要求,pimpl 可能不是一个好的选择。
Effectively, yes, though there are techniques, such as those discussed by Herb Sutter in "The Fast Pimpl Idiom," that can be used to eliminate or speed up the heap allocation, at the cost of greater complexity.
Only if it's necessary to do so (i.e., only if your users would be surprised by the fact that your class performed heap allocation). Many classes perform heap allocation, including many of those in the C++ standard library (all of the containers, for example).
Possibly :-). Unless you have high performance requirements for your class or you expect instances of your class to be created and destroyed extremely frequently, I wouldn't worry too much about it. Of course, if you do have significant performance requirements, pimpl may not be a good choice.
是的。
我认为这种评论过于激进:) 如果你的类对性能如此关键,也许你应该避免使用 PIMPL 习惯用法。如果您代表一个数字,这可能会引起关注并值得注意。如果您隐藏数据库连接的实现,则不值得评论:)
是的,这对用户来说有点明显,但同样可能不值得自己担心。
这是一个权衡,但如果你的类足够复杂,能够真正从 pimpl 习惯中获益,你可能可以假设堆分配是可以的。如果我使用你的图书馆,我可能不会担心。
Yep.
I'd consider that over aggressive commenting :) If your class is so performance critical, perhaps you should avoid the PIMPL idiom. If you're representing a number, this might be concerning and worth noting. If you're hiding implementation of a database connection, not worth the comment :)
Yeah, it's a little more obvious to the user, but again probably not worth concerning yourself over.
There's a tradeoff, but if your class is complex enough to really gain from the pimpl idiom, you probably can assume a heap allocation is OK. If I were using your library, it probably wouldn't concern me.