class MyClassPrivate
{
//My members.
};
//and then
class MyClass {
private:
MyClassPrivate* const d;
};
使用这种'模式'的原因是什么?它是如何正确调用的?
答案 0 :(得分:4)
这称为“实施指针”或“pimpl”。见http://en.wikibooks.org/wiki/C++_Programming/Idioms#Pointer_To_Implementation_.28pImpl.29
当你使用这种模式时,你会转发声明实现类,并在其他地方声明主体,即:
// header
class MyClassPrivate;
class MyClass {
public:
MyClass();
~MyClass();
private:
MyClassPrivate* const d;
};
// cpp
class MyClassPrivate {
};
MyClass::MyClass() : d(new MyClassPrivate) {}
MyClass::~MyClass() { delete d; }
这样做的好处是MyClass
的实施不会向MyClass
的其他用户公开。如果实现发生更改,则MyClass
的其他用户不需要重新编译。还不需要公开任何必须包含在成员中的头文件,这样可以缩短编译时间。
答案 1 :(得分:3)
最常用的是Pimlp成语。
Pimpl习语描述了制作头文件的方法 不受变化的影响。你经常会听到“避免改变你的想法”这样的建议 公共界面!“所以你可以修改你的私人界面,但是如何 当头文件定义私有时,你能避免重新编译吗? 方法。这就是Pimpl的作用 - 减少编译时的损失 您的私人界面会更改[3]。
来自Here:
优点:
缺点:
怎么做:
答案 2 :(得分:1)
当您想要将界面与iplementation分开时,可以将此用于PIMPL idiom。
许多设计模式也使用私有属性的“指针”,例如策略模式。此模式允许您在运行时选择不同的算法。
此外,如果您对数据的操作遵循相同的接口,您可以将数据封装在私有类中,使此类成为层次结构的一部分,并在运行时(或编译时)在不同的数据实现之间切换对于这个问题 :))。
这方面的一个很好的例子是一个包含多边形数据的几何类。每个Polygon提供对点的访问,您还可以删除Polygon边缘并执行各种其他拓扑操作。如果使用deletePoint,addPoint,swapEdge等方法为Polygon类提供抽象基类,则可以测试不同的Polygon实现。
您可以直接将多边形定义为Point类型列表,并将这些点存储在不同的容器(列表或向量)中。 Polygon类可以通过间接寻址来定义,其中多边形实际上是点列表的ID列表(我在谈论一般意义上的列表)。这样,您可以测试PolygonGeometry类的不同算法,并查看它们如何与differtn Polygon实现一起使用。
这背后有一个设计原则:首选组合继承。无论何时使用Composition,并且依赖于在运行时确定的类型,您将拥有私有属性指针。