【发布时间】:2013-01-08 14:23:38
【问题描述】:
我正在尝试围绕外部 C API 创建一个仅包含标头的 C++ 库。
C API 使用void * 指针作为句柄。
想法是这样的:
// resource.hpp
class Resource {
public:
// RAII constructor, destructor, etc.
// ...
void do_something(const Handle & h) {
do_something_impl( (void *) h);
}
};
// handle.hpp
class Handle
{
public:
Handle(size_t n, const Resource & res)
: p_(res.allocate(n)), res_(res) {}
// cast operation
operator void *() const { return p_; }
private:
void * p_;
Resource & res_;
};
这里的问题是 (a) Handle 必须保持对 Resource 的引用,并且 (b) Resource 需要能够将 Handle 转换为 void *。不幸的是,这会导致循环依赖。
关于如何重组这个有什么想法吗?
注意:答案不是简单地“包含 xxx.hpp”或前向声明其中一个类。 这需要以某种方式重组,我只是不太明白如何。
将class Handle 作为前向声明添加到资源文件的顶部不起作用,因为(void *) 转换是资源仍然看不到的句柄定义的一部分。同样,将强制转换更改为 void * ptr() 成员函数会导致同样的问题。
将函数定义移动到 .cpp 文件也不是一个答案——它必须是仅标题。
【问题讨论】:
-
除了使用前向声明之外,请确保使用标头保护。
-
@Joe:前向声明在这里不起作用(见编辑)。
标签: c++ circular-dependency raii