Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/144.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
仅标题库循环依赖项 我试图在外部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_; };_C++_Circular Dependency_Raii - Fatal编程技术网

仅标题库循环依赖项 我试图在外部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_; };

仅标题库循环依赖项 我试图在外部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_; };,c++,circular-dependency,raii,C++,Circular Dependency,Raii,这里的问题是:(a)句柄必须保留对资源的引用,(b)资源需要能够将句柄强制转换为void*。不幸的是,这会导致循环依赖 有没有关于如何重组的想法 注意:答案不是简单地“include xxx.hpp”或向前声明其中一个类。 这需要以某种方式进行重组,我只是不太明白如何重组 将类句柄作为前向声明添加到资源文件顶部是不起作用的,因为(void*)强制转换是句柄定义的一部分,资源仍然无法看到。同样,将强制转换更改为void*ptr()成员函数也会导致相同的问题 将函数定义移动到.cpp文件也不是一个答

这里的问题是:(a)句柄必须保留对资源的引用,(b)资源需要能够将句柄强制转换为void*。不幸的是,这会导致循环依赖

有没有关于如何重组的想法

注意:答案不是简单地“include xxx.hpp”或向前声明其中一个类。 这需要以某种方式进行重组,我只是不太明白如何重组

类句柄
作为前向声明添加到资源文件顶部是不起作用的,因为
(void*)
强制转换是句柄定义的一部分,资源仍然无法看到。同样,将强制转换更改为
void*ptr()
成员函数也会导致相同的问题


将函数定义移动到.cpp文件也不是一个答案——它只需要是头文件。

不要将头文件包含到彼此中,而是对类进行前向声明。这样,它们可以用作引用或指针

因此,在resource.hpp中:

class Handle;

class Resource {
public:
    // RAII constructor, destructor, etc.
    // ...
    void do_something(const Handle & h) {
        do_something_impl( (void *) h);
    }
};
在handle.hpp中:

class Resource;

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_;
};


由于在
do\u something
函数中使用了
void*
typecasting操作符,因此必须将该实现移动到单独的源文件中。在该源文件中,您可以同时包含两个头文件,因此可以访问所有函数。

不要将头文件包含在彼此中,而是对类进行正向声明。这样,它们可以用作引用或指针

因此,在resource.hpp中:

class Handle;

class Resource {
public:
    // RAII constructor, destructor, etc.
    // ...
    void do_something(const Handle & h) {
        do_something_impl( (void *) h);
    }
};
在handle.hpp中:

class Resource;

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_;
};


由于在
do\u something
函数中使用了
void*
typecasting操作符,因此必须将该实现移动到单独的源文件中。在该源文件中,您可以同时包含两个头文件,因此可以访问所有函数。

好吧,这是一个很好的解决方案(再次!):

//resource.hpp
班级资源;
模板类句柄;
类资源{
公众:
//RAII构造函数、析构函数等。
// ...
void do_某事(const Handle&h){
做一些简单的事((void*)h);
}
};
//handle.hpp
模板
类句柄{
公众:
句柄(大小、常量、资源和资源)
:p_(res.allocate(n)),res_(res){}
//铸造操作
运算符void*()常量{return p_;}
私人:
void*p;
TResource&res;
};

好吧,这是救援的模板(再一次!):

//resource.hpp
班级资源;
模板类句柄;
类资源{
公众:
//RAII构造函数、析构函数等。
// ...
void do_某事(const Handle&h){
做一些简单的事((void*)h);
}
};
//handle.hpp
模板
类句柄{
公众:
句柄(大小、常量、资源和资源)
:p_(res.allocate(n)),res_(res){}
//铸造操作
运算符void*()常量{return p_;}
私人:
void*p;
TResource&res;
};

在使用转发声明的基础上,确保使用标题保护。@Joe:转发声明在这里不起作用(请参见编辑)。在使用转发声明的基础上,确保使用标题保护。@Joe:转发声明在这里不起作用(请参见编辑)。@Joachim--在vs2010中,这给出了“无法从'const Handle&h'转换为'void*';源或目标的类型不完整。换句话说,Resource无法看到
操作符void*()
。另外,将
类资源添加到handle.hpp将不起作用,因为handle需要看到Resource.allocate()成员函数@DavidH然后您必须在
handle.hpp
中包含
resource.hpp
文件。只要你不做相反的事情就好了。至于错误,这是因为您试图将非指针类型转换为指针类型。@Joachim--转换运算符的整个要点就是将句柄类型转换为指针。你能建议一个不同的方法吗?void*ptr()成员函数会给出相同的错误并导致相同的问题。@DavidH难道不能使用运算符的地址来实际获取一个真正的指针吗?@Joachim——在vs2010中,这会给出“无法从'const Handle&h'转换为'void*';源或目标的类型不完整。换句话说,Resource无法看到
操作符void*()
。另外,将
类资源添加到handle.hpp将不起作用,因为handle需要看到Resource.allocate()成员函数@DavidH然后您必须在
handle.hpp
中包含
resource.hpp
文件。只要你不做相反的事情就好了。至于错误,这是因为您试图将非指针类型转换为指针类型。@Joachim--转换运算符的整个要点就是将句柄类型转换为指针。你能建议一个不同的方法吗?void*ptr()成员函数将给出相同的错误并导致相同的问题。@DavidH难道不能使用运算符的地址来实际获取一个真正的指针吗?