【问题标题】:what C++ idiom / pattern is this这是什么 C++ 习语/模式
【发布时间】:2015-07-21 08:00:13
【问题描述】:

我还是 C++11 的新手。

前段时间我问了以下问题:
Best method to implement an abstract factory pattern

为了进一步研究,我想知道这个C++习语叫什么名字。

我在这里称它为pimpl,但我不确定这是否是正确的名称。

整个事情的目的是在从工厂返回 Shape 对象时隐藏原始或智能指针。使用这种“模式”工厂就能返回一个相同的类型,具体实现会封装在对象内部。

它也与decorator 非常相似,只是它不装饰任何东西。

人们也可能会发现与adapter 的相似之处,除了外部接口与“内部”接口相同。

class PimplShape : public Shape{
    Shape *sh;
public:
    PimplShape(Shape *sh) : sh(sh){
    }

    virtual ~PimplShape() override{
        delete sh;
    }

    virtual void process() override {
        sh->process();
    }
};

【问题讨论】:

  • "当从工厂返回 Shape 对象时" 这意味着如何在这里完成?您没有返回包含的形状的方法。此外,这将创建一个完整的 Shape,它本身必须包含指向另一个 Shape 的指针。我不确定这就是你想要的,是吗?对我来说似乎是多余的。
  • stackoverflow.com/questions/31494734/… - 检查这个。如果使用它,工厂将始终返回一个相同的类型。具体实现会封装在这个类型中。
  • 你的班级做了哪些 unique_ptr 没有做的事情?
  • @Pumkko - 这是非常好的一点,它什么也不做,除了你不需要取消引用它。
  • 忘记所有那些“成语”和“模式”。它们都不是经验法则。最重要的规则是常识,根据它和你的具体情况,你可以自己想出一个合适的“模式”。

标签: c++ decorator idioms pimpl-idiom


【解决方案1】:

我个人的看法是,你在多个成语之间编造了一些东西。

pimpl 的想法是隐藏提供实际功能的内部类,以便您可以随心所欲地更改而不影响用户(Qt 广泛这样做)。如果我们查看您的代码,则有两件事禁止这样做 - 继承和方法在类定义中实现的事实(因此内部类的方法对类的用户是可见的)。在您的情况下,正确的 pimpl 将是:

// PimplShape.h
class Shape;

class PimplShape
{
    Shape *sh_;
public:
    PimplShape(Shape *sh);
    ~PimplShape();
    void process();
};

// PimplShape.cpp
#include "Shape.h" // Defines Shape::process() so PimplShape can use it

PimplShape::PimplShape(Shape *sh) : sh_(sh)
{

}

PimplShape::~PimplShape()
{
    delete sh_;
}

void PimplShape::process()
{
    sh_->process();
}

正如您在此处看到的,Shape 类对PimplShape.h 文件的任何用户都是隐藏的。

如果我们从功能的角度来看您的示例,似乎您想要实现CRTP,但这不是实现它的方法。

【讨论】:

  • 我不认为“impl”是一个抽象类在 Pimpl 模式中是典型的(我从 Nick 的另一个问题的上下文中知道 Shape 是一个抽象类)。您通常不需要隐藏抽象类。
  • @ChrisDrew 这只是为了展示pimpl 在给定的代码示例中的样子,以便尼克可以看到不同之处:) 正如我所说,他所拥有的似乎介于许多之间成语,所以应该澄清一下他要达到的目标是什么。
猜你喜欢
  • 2017-08-21
  • 2012-03-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-05
  • 2010-09-23
  • 1970-01-01
  • 2015-06-01
相关资源
最近更新 更多