2012-04-13 82 views
2

比方說,我有一個C++接口通過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 - > ...」東西?

+1

派生創建一個類做它與私有繼承, 。 – 2012-04-13 13:58:35

+1

可以將'impl'聲明爲'Iface *'而不是'IfaceImpl *'嗎? – dasblinkenlight 2012-04-13 13:59:13

+0

@彼得,非常好的評論,儘管它只解決了部分問題。 (你仍然願意爲每種方法編寫它),並且有一些中間類可能想要做些稍微不同的事情的弱點。我真正想要的是「這裏有兩件完全相同的東西,把它們綁在一起*就像這樣*」template/macro/whatever。 – idij 2012-04-13 14:21:42

回答

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是不同類的,只要它們是從一

+0

它會如何精確地工作,你能擴展嗎?據推測InTheMiddle不再實現Iface?之後? – idij 2012-04-13 14:41:06

+0

@idij:好的更新了一些更多的信息。 – 2012-04-13 19:47:32

+0

這非常有趣。謝謝你的解釋。 – idij 2012-04-13 20:43:04

0

我相信這是使用句柄類(Pimpl idiom)的一個缺點。爲了支持打破/關閉原則,是否需要保持編譯時間的絕對值?通常在今天的編譯器和CPU中,Pimpl習慣用法不像以前那麼多。

+3

該習語還用於共享庫,因此實現可以更改但保留相同的接口。這對於兼容性至關重要。 – 2012-04-13 14:04:22

相關問題