2011-08-21 70 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