class MyClassPrivate
{
//My members.
};
//and then
class MyClass {
private:
MyClassPrivate* const d;
};
使用这种“模式”的原因是什么?它是如何正确调用的?
class MyClassPrivate
{
//My members.
};
//and then
class MyClass {
private:
MyClassPrivate* const d;
};
使用这种“模式”的原因是什么?它是如何正确调用的?
这称为“指向实现”或“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
不需要重新编译。任何必须为成员包含的头文件也不需要公开,这提高了编译时间。
最常用的是Pimlp成语。
Pimpl 成语描述了一种使您的头文件不受更改的方法。您经常听到诸如“避免更改您的公共界面!”之类的建议。所以你可以修改你的私有接口,但是当你的头文件定义私有方法时,如何避免重新编译。这就是 Pimpl 所做的 - 当您的私有接口更改时减少编译损坏[ 3 ]。
从这里:
好处:
缺点:
怎么做:
当您想将接口与实施分开时,您可以将其用于PIMPL idiom 。
许多设计模式也使用指向私有属性的“指针”,例如Strategy Pattern。此模式允许您在运行时选择不同的算法。
此外,如果您使数据的操作遵循相同的接口,则可以将数据封装在私有类中,使该类成为层次结构的一部分,并在运行时(或编译时)在不同的数据实现之间切换:))。
一个很好的例子是保存多边形数据的几何类。每个多边形都提供对点的访问,您还可以删除多边形边缘并进行各种其他拓扑操作。如果为 Polygon 类提供一个抽象基类,提供 deletePoint、addPoint、swapEdge 等方法,就可以测试不同的 Polygon 实现。
您可以直接将多边形定义为点类型的列表,并将点存储在不同的容器(列表或向量)中。Polygon 类可以通过间接寻址来定义,其中多边形实际上是点列表的 ID 列表(我说的是一般意义上的列表)。这样,您可以测试 PolygonGeometry 类的不同算法,并了解它们如何与不同的 Polygon 实现一起工作。
这背后有一个设计原则:Prefer Composition to Inheritance。每当您使用组合并且依赖于在运行时确定的类型时,您将拥有一个私有属性指针。