c++ 使用unique_ptr作为不透明对象id

kq4fsx7k  于 2023-04-01  发布在  其他
关注(0)|答案(2)|浏览(133)

我通过执行以下操作在我的项目中隐藏了第三方C++图形库(LEMON图形库)的实现细节:
API. h文件

class Node;
using NodeId = unique_ptr<Node>;
class ProgramGraph {
private:
  class ProgramGraphImpl;
  ProgramGraphImpl* pimpl;
public:
  ProgramGraph();
  NodeId add_instr_node(int opcode, const string& desc, BlockId& parent);
  ...
};

API.cpp文件

class Node {
public:
  ListDigraph::Node node;
  Node(ListDigraph::Node node) : node(node) {}
  ~Node() {}
};

class ProgramGraphImpl {
  NodeId add_instr_node(int opcode, const string& desc, BlockId& parent) {
    ListDigraph::Node n = pg.addNode(); // this is from the 3rd party library
    unique_ptr<Node> uq = make_unique<Node>(Node(n));
    node_map[n] = Instr(opcode, desc, parent); // Instr is another class defined in API.cpp
    return uq;
  }
  ...
};

NodeId ProgramGraph::add_instr_node(int opcode, const string& desc, BlockId& parent) {
  return pimpl->add_instr_node(opcode, desc, parent);
}

我在some_other_file.cpp中使用如下API:

#include "API.h"
...
    const NodeId& currMI = pg.add_instr_node(opcode, opcode_desc, block_id);
...

当我编译它时,我得到下面的错误(error: invalid application of 'sizeof' to an incomplete type program_graph::Node)-任何想法?谢谢。
/Applications/ Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX12.3.sdk/usr/include/c++/v1/__memory/unique_ptr.h:53:19: error:invalid application of 'sizeof' to an incomplete type 'program_graph::Node' static_assert(sizeof(_Tp)〉0,^~~~~~~~~~~~ /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX12.3.sdk/usr/include/c++/v1/__memory/unique_ptr.h:318:7:note:in instantiation of member function 'std::default_delete<program_graph::Node>::operator()' requested here _ptr.second()(__tmp);^ /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX12.3.sdk/usr/include/c++/v1/__memory/unique_ptr.h:272:19:注意:在成员函数'std::unique_ptr<program_graph::Node>::reset'的示例化中,此处请求~unique_ptr(){ reset();} ^ some_other_file.cpp:151:36:注意:在成员函数'std::unique_ptr<program_graph::Node>::~unique_ptr'的示例化中,此处请求const NodeId& currMI = pg.add_instr_node(操作码,操作码描述,块标识);

tzdcorbm

tzdcorbm1#

您在“API.cpp”文件中重新定义了类ProgramGraph
尝试删除它,重新编译并提供更详细的代码版本。
很简单:

class Node {
public:
    Node()  {}
    ~Node() {}
};
NodeId ProgramGraph::add_instr_node(int opcode, const string& desc/*, BlockId& parent*/) {
    /*return pimpl->add_instr_node(opcode, desc, parent);*/
    return nullptr;
}
wkftcu5l

wkftcu5l2#

需要使用自定义删除器,例如:

using NodePtr = std::unique_ptr<Node,void(*)(Node*)>;

然后在.cpp文件中提供删除器:

void delete_node(Node* node) { delete node; }
...
NodePtr uq{new Node(n), delete_node};

因为默认的删除器不能处理不完整的类型。

相关问题