开发者

C++ wrap C struct *and* and functions

I'm trying to wrap a C library which uses patterns like this:

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

In c++, I'd like to be able to do something like

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();

Obviously, CXXOther wraps a pointer to a CXXThing as well. So the problem I'm encountering is that essentially I'd like to just "insert" functions and members into existing structs (I think this is known as the "Mixin" idea).

The problem is that if I include a Thing as an element of the CXXThing, then I don't know how I'd declare the constructor, and if I include a pointer to the wrapped class, then I have an extra level of useless indirection.

How should I wrap it开发者_StackOverflow so that this is possible? (An answer of "What you want to do is not best/possible... here is the proper way" is also acceptable.)


Instead of using auto_ptrs, you can use the RAII idiom more directly. Here's one way you can do it:

A CXXThing class that wraps a 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;
};

A CXXOther class that wraps an 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; 
};

Translating your C code into C++ code with the above classes:

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜