Tag: pimpl idiom

我应该使用shared_ptr还是unique_ptr

我一直在使用pimpl习语做一些对象,但我不确定是否使用std::shared_ptr或std::unique_ptr 。 我明白, std::unique_ptr更有效率,但这对我来说并不是什么大问题,因为无论如何这些对象都是相对重量级的,所以std::shared_ptr超过std::unique_ptr的代价相对较小。 我目前正在与std::shared_ptr只是因为额外的灵活性。 例如,使用std::shared_ptr允许我将这些对象存储在散列表中以便快速访问,同时仍然可以将这些对象的副本返回给调用者(因为我相信任何迭代器或引用可能会很快变得无效)。 然而,这些对象实际上并没有被复制,因为变化会影响到所有的副本,所以我想知道,也许使用std::shared_ptr并允许副本是某种反模式或坏东西。 它是否正确?

皮姆普成语在实践中

关于这个pimpl习语 ,有几个问题,但是我更加好奇它在实践中被多less次使用。 我知道性能和封装之间有一些折衷,加上一些debugging烦恼由于额外的redirect。 那么,这是应该在每一个class级,或全或无的基础上采取的东西? 这是最佳做法还是个人喜好? 我意识到这有点主观,所以让我列出我的首要任务: 代码清晰 代码可维护性 性能 我总是认为我需要在某个时候将我的代码作为一个库来公开,所以这也是一个考虑因素。 编辑:任何其他选项来完成同样的事情将是值得欢迎的build议。

我如何使用unique_ptr pimpl?

这里是我尝试使用unique_ptr for pimpl时看到的简化。 我select了unique_ptr,因为我真的希望类拥有指针 – 我希望pimpl指针和类的生命期是相同的。 无论如何,这是标题: #ifndef HELP #define HELP 1 #include <memory> class Help { public: Help(int ii); ~Help() = default; private: class Impl; std::unique_ptr<Impl> _M_impl; }; #endif // HELP 这里是来源: #include "Help.h" class Help::Impl { public: Impl(int ii) : _M_i{ii} { } private: int _M_i; }; Help::Help(int ii) : _M_impl{new Help::Impl{ii}} { […]

Pimpl成语与纯虚拟类接口

我想知道是什么让程序员selectPimpl成语或纯虚拟类和inheritance。 我明白,pimpl习语为每个公共方法和对象创build开销带来了一个明确的额外间接。 纯虚拟类在另一方面带有隐式间接(vtable)的inheritance实现,我明白,没有对象创build开销。 编辑 :但是你会需要一个工厂,如果你从外面创build对象 是什么使得纯粹的虚拟阶级比俚语成语更不可取?

什么构成C ++ 11中的“从…移到”对象的有效状态?

我一直在试图围绕C ++ 11中的移动语义如何工作,而且我在理解移动对象需要满足的条件方面遇到了很多麻烦。 看看这里的答案并不能真正解决我的问题,因为看不到我们的问题,因为我们无法看出如何以合理的方式将它应用于pimpl对象,尽pipe移动语义对于pimpls来说是完美的 。 我的问题的最简单的例子涉及到pimpl的成语,就像这样: class Foo { std::unique_ptr<FooImpl> impl_; public: // Inlining FooImpl's constructors for brevity's sake; otherwise it // defeats the point. Foo() : impl_(new FooImpl()) {} Foo(const Foo & rhs) : impl_(new FooImpl(*rhs.impl_)) {} Foo(Foo && rhs) : impl_(std::move(rhs.impl_)) {} Foo & operator=(Foo rhs) { std::swap(impl_, rhs.impl_); return *this; } void […]

如何使用Qt的PIMPL成语?

PIMPL代表执行进程 。 实现代表“实现细节”:类的用户不需要关心的东西。 Qt自己的类实现通过使用PIMPL惯用语将接口与实现完全分开。 然而,由Qt提供的机制没有logging。 如何使用它们? 我想这是关于“我如何PIMPL”在Qt的规范问题。 答案将由下面显示的一个简单的坐标input对话框界面来激励。 当我们有一个半复杂的实现时,使用PIMPL的动机变得明显。 进一步的动机在这个问题上给出。 即使是一个相当简单的类也必须在其接口中引入大量其他头文件。 基于PIMPL的界面相当干净可读。 // CoordinateDialog.h #include <QDialog> #include <QVector3D> class CoordinateDialogPrivate; class CoordinateDialog : public QDialog { Q_OBJECT Q_DECLARE_PRIVATE(CoordinateDialog) #if QT_VERSION <= QT_VERSION_CHECK(5,0,0) Q_PRIVATE_SLOT(d_func(), void onAccepted()) #endif QScopedPointer<CoordinateDialogPrivate> const d_ptr; public: CoordinateDialog(QWidget * parent = 0, Qt::WindowFlags flags = 0); ~CoordinateDialog(); QVector3D coordinates() const; Q_SIGNAL void […]

pImpl成语在实践中是否真的被使用?

我正在阅读Herb Sutter的书“Exceptional C ++”,并且在那本书中我学习了这个pImpl习语。 基本上,这个想法是为一个class的private对象创build一个结构,并dynamic地分配它们来减less编译时间 (并且也以更好的方式隐藏私有实现)。 例如: class X { private: C c; D d; } ; 可以改成: class X { private: struct XImpl; XImpl* pImpl; }; 在CPP中定义如下: struct X::XImpl { C c; D d; }; 这看起来很有趣,但是我从来没有见过这种方法,在我工作过的公司,也没有见过源代码的开源项目。 那么,我想知道这个技术在实际中是否真的被使用了? 我应该在任何地方或谨慎使用吗? 这种技术是否被推荐用于embedded式系统(性能非常重要)?

为什么要使用“PIMPL”习语呢?

背景资料: PIMPL成语 (实现指针)是一种实现隐藏的技术,在这种技术中,公共类包装一个结构或类,这些结构或类在公共类所属的库之外是看不到的。 这隐藏了库的用户的内部实现细节和数据。 当实现这个习惯用法时,为什么要把公共方法放在pimpl类而不是公共类中,因为公共类方法的实现将被编译到库中,而用户只有头文件? 为了说明,这段代码把Purr()实现放在impl类上,并且包装它。 为什么不直接在公共课上实施Purr? // header file: class Cat { private: class CatImpl; // Not defined here CatImpl *cat_; // Handle public: Cat(); // Constructor ~Cat(); // Destructor // Other operations… Purr(); }; // CPP file: #include "cat.h" class Cat::CatImpl { Purr(); … // The actual implementation can be anything }; Cat::Cat() […]