2011-08-21 74 views
3

我試圖總結其採用的模式是這樣一個C庫:C++包裝C結構*和*和功能

Thing* x= new_thing_("blah"); 
Thing* tmp= thing_copy(x); 
free_thing(tmp); 
Other* y=get_other(x,7); 
char* message=get_message(x,y); 
free_thing(x); 
free_other(y); 

在C++中,我希望能夠做到像

auto_ptr<CXXThing> x=new CXXThing("blah"); 
auto_ptr<CXXThing> tmp=new CXXThing(*x); 
auto_ptr<CXXOther> y=x->get_other(7); 
char* message = y->get_message(); 

顯然,CXXOther也包裝了一個指向CXXThing的指針。所以我遇到的問題是,我基本上只想將功能和成員「插入」現有結構(我認爲這被稱爲「Mixin」思路)。

的問題是,如果我有一個東西作爲CXXThing的一個元素,那麼我不知道怎麼我聲明構造,如果我包括指針到被包裝類的話,我有額外的無用間接。

我該如何包裝它才能做到這一點? (「你想做什麼不是最好的/可能的......這是正確的方式」的答案也是可接受的。)

+0

I可能是錯誤的,但我的印象是,您可能會返回auto_ptrs來表達傳輸對象的所有權(http://www.gotw.ca/publications/using_auto_ptr_effectively.htm) –

+0

這完全正確。但是,對於上述情況,將Thing和Other放在自己的類中會更簡單,並且會導致用戶更容易使用的類。 –

回答

9

而不是使用auto_ptr s,可以更直接地使用RAII習語。這裏有一種方法可以做到這一點:

一個CXXThing類,包裝了一個Thing

class CXXThing 
{ 
public: 
    // Acquire a Thing 
    explicit CXXThing(const char* str) : x(::new_thing_(str)) {} 
    // Copy a Thing 
    CXXThing(const CXXThing& rhs) : x(::thing_copy(rhs.x)) {} 
    // Copy-and-swap idiom 
    CXXThing& operator=(CXXThing rhs) 
    { 
     swap(*this, rhs); 
     return *this; 
    } 
    // Release a Thing 
    ~CXXThing() { ::free_thing(x); } 

    friend void swap(CXXThing& lhs, CXXThing& rhs) 
    { 
     Thing* tmp = lhs.x; 
     lhs.x = rhs.x; 
     rhs.x = tmp; 
    } 

private: 
    Thing* x; 
    friend class CXXOther; 
}; 

一個CXXOther類封裝了一個Other

class CXXOther 
{ 
public: 
    // Acquire an Other 
    explicit CXXOther(CXXThing& thing, int i) : y(::get_other(thing.x, i)) {} 
    // Release an Other 
    ~CXXOther() { ::free_other(y); } 
    // Get a message 
    char* get_message(const CXXThing& x) { return ::get_message(x.x, y); } 
private: 
    // Instaces of Other are not copyable. 
    CXXOther(const CXXOther& rhs); 
    CXXOther& operator=(const CXXOther& rhs); 
    Other* y; 
}; 

翻譯你的C代碼轉換成C++的代碼上述種類:

int main() 
{ 
    CXXThing x("blah"); 

    { 
     CXXThing tmp = x; 
    } // tmp will go away here. 

    CXXOther y(x, 7); 
    char* msg = y.get_message(x); 
    return 0; 
} 
+0

是否需要額外的間接程度? –

+3

好吧,這個類正在封裝一個C風格的接口來提供一個C++接口,所以是的,額外的間接性是必要的。但是我的代碼只有一個間接級別,而你的問題中的第二個代碼片段有兩個:'auto_ptr '和'CXXThing'封裝了一個'Thing *'。 –

+1

考慮'使用std :: swap;交換(lhs.x,rhs.x);'在你的朋友交換中更簡潔,一行更短。 – Flame