引用计数结构暴露POD接口

时间:2014-06-20 09:55:28

标签: c++ reference-counting pod binary-compatibility

我目前有一个结构声明了一个复制构造函数和一个析构函数,并保留了一个pimpl对象的引用计数。这允许我按值传递这个结构。我需要重构它,因为我希望它有一个POD接口,因为它现在需要从使用旧C ++风格的代码中使用它的库的一部分。 因此,我必须删除复制构造函数和析构函数。在我删除之后,我无法弄清楚如何保持这种良好的"传递价值",多种所有权机制。共享指针不是一个选项,因为该结构被用作其他类的方法的参数,这些类也需要从库用户的角度看作POD。

struct Foo {
  Foo(const Foo&);
  const Foo& operator=(const Foo&);
  ~ Foo();
private:
  void* pimpl;
};

struct MainLibrary {
   void DoSomething(Foo param);
}

用户代码现在就像:

MainLibrary ml;
{
  Foo a;
  ml.doSomething(a);
}

此时,a变量可以在主库中保存很长时间。为了提高效率,Foo的内部每次都不能被深层复制,这就是为什么pimpl实现保持每次复制Foo实例时递增的引用计数器的原因,每次Foo实例都会递减被毁了。

1 个答案:

答案 0 :(得分:1)

评论过多......如下所示。客户端包括foo03.h,它们的使用应保持不受影响。您的C ++ 11实现是通过" C"层。如果搜索"将C ++代码暴露给C"您可以找到很多示例。或类似....

foo03.h:

extern "C"
{
    void* foo_constructor();
    void* foo_constructor2(void* rhs);
    void foo_assign(void* lhs, void* rhs);
    void foo_destructor(void* p_this);
}

struct Foo {
    Foo() { p_ = foo_constructor(); }
    Foo(const Foo& rhs) { p_ = foo_constructor2(rhs.p_); }
    const Foo& operator=(const Foo& rhs) { foo_assign(p_, rhs.p_); return *this; }
    ~Foo() { foo_destructor(p_); }
  private:
    void* p_;
};

foo11.h:

// up to you whether you call this Foo (relying on mangling differences to avoid conflicts when
// linking with C++03 objects), FooImpl, put it in a namespace ala Impl::Foo etc..
struct FooImpl {
    FooImpl() { ... }
    FooImpl(const FooImpl&) { ... }
    const FooImpl& operator=(const FooImpl& rhs) { ... }
    ~FooImpl() { ... }
};

extern "C"
{
    void* foo_constructor() { return new FooImpl(); }
    void* foo_constructor2(void* rhs) { return new FooImpl(*(FooImpl*)rhs); }
    void foo_assign(void* lhs, void* rhs) { *(FooImpl*)lhs = *(FooImpl*)rhs; }
    void foo_destructor(void* p_this) { delete (FooImpl*)p_this; }
}