2

假设我有一个 C++ 接口

class Iface
{
public:
    virtual ~Iface () {}
    virtual void foo () = 0;
    virtual void bar () = 0;
};

而且我有一些类需要在一侧公开它并在其他地方实现它。我发现很常见的是我最终会在中间有一堆类,它们基本上做这样的事情:

class InTheMiddleSomewhere
    : public Iface // amongst other things
{
public: // Iface
    virtual void foo () { if (impl) impl->foo (); }
    virtual void bar () { if (impl) impl->bar (); }
private:
    IfaceImpl* impl;
};

随着接口的扩展、增殖和变化,编写和维护变得很烦人。

问:有没有比手工编写所有“if (impl) impl->...”代码更好的(或多或少是自动的)方法来实现完整接口的传递?

4

2 回答 2

1

您可以将调用绑定到函数对象中,然后只通过函数对象(而不是为接口的每个成员函数进行委托调用)。

考虑以下:

struct I
{
    virtual R1 f1(A1, B1, ..., Z1) = 0;
    virtual R2 f2(A2, B2, ..., Z2) = 0;
    .
    .
    virtual Rn fn(An, Bn, ..., Zn) = 0;
};

现在我有一些 I 的实现:

struct : I
{
    ...
} x, y, z;

所以我可以调用 x、y 和 zs 函数,如:

Ri xri = x.fi(ai, bi, ..., zi);
Ri yri = y.fi(ai, bi, ..., zi);
Ri zri = z.fi(ai, bi, ..., zi);

或者我可以将调用绑定到 I 接口的方法,如下所示:

function<Ri(I&)> g = bind(&I::fi, _1, ai, bi, ..., zi);

然后:

Ri xri = g(x);
Ri yri = g(y);
Ri zri = g(z);

即使 x、y 和 z 是不同的类,只要它们是从 I 派生的,这也有效。

于 2012-04-13T14:20:26.490 回答
0

我相信这是使用句柄类(Pimpl idiom)的一个缺点。是否绝对需要缩短编译时间以支持打破打开/关闭原则?通常对于今天的编译器和 CPU,Pimpl 惯用语的使用量不如以前。

于 2012-04-13T14:00:26.790 回答