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;
};

インターフェースが拡大、増殖、変化するにつれて、これを作成して維持するのは面倒です。

Q: すべての "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;
};

今、私はいくつかの実装を持っています:

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 イディオム) を使用することの 1 つの欠点だと思います。オープン/クローズの原則を破るために、コンパイル時間を短縮する絶対的な必要性はありますか? 通常、今日のコンパイラと CPU では、Pimpl イディオムは以前ほど使用されていません。

于 2012-04-13T14:00:26.790 に答える