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