如何深度拷贝包含子图的Boost图顶点属性?
问题描述
我有一个带自定义属性的Boost图,目前通过自定义拷贝结构体实现了部分属性拷贝,但顶点属性里的BGType* _subGraph字段只是浅拷贝,导致新图和旧图共享子图实例。需要实现这个字段的深度拷贝,该怎么处理?
相关代码
BGType 类型定义
using BGType = boost::adjacency_list<boost::vecS, boost::vecS, boost::bidirectionalS, // 顶点属性 vertexProps, // 边属性 edgeProps, // 图属性 graphProps>;
vertexProps 类定义(vertexProps.h)
class vertexProps { public: explicit vertexProps(const std::string *moduleName = nullptr, const std::string *name = nullptr, long refPtr = 0 ) : _refPtr(refPtr) { _moduleName = moduleName ? *moduleName : ""; _name = name ? *name : ""; }; std::string _moduleName; std::string _name; BGType *_subGraph = nullptr; BGType *_graph = nullptr; long _refPtr; // 补充原代码遗漏的成员 };
自定义顶点拷贝结构体
struct CustomVertexCopy { BGType const &g1; BGType &g2; void operator()(BGType::vertex_descriptor v1, BGType::vertex_descriptor v2) const { vertexProps const &p1 = g1[v1]; vertexProps &p2 = g2[v2]; p2._subGraph = p1._subGraph; // 此处为浅拷贝,需修改 p2._graph = p1._graph; p2._moduleName = p1._moduleName; p2._name = p1._name; p2._refPtr = p1._refPtr; } };
edgeProps 类与自定义边拷贝结构体(edgeProps.h)
class edgeProps { public: explicit edgeProps(std::string name = "") : _name(name){}; std::string _name; }; struct CustomEdgeCopy { BGType const &g1; BGType &g2; void operator()(BGType::edge_descriptor e1, BGType::edge_descriptor e2) const { g2[e2]._name = g1[e1]._name; } };
拷贝调用代码(someFunction.cpp)
void OnClick(BGType* bgNew) { // 其他业务代码 BGType* oldBg = new BGType; boost::copy_graph( *bgNew, *oldBg, boost::vertex_copy(CustomVertexCopy{*bgNew, *oldBg}).edge_copy(CustomEdgeCopy{*bgNew, *oldBg})); boost::get_property(*oldBg) = boost::get_property(*bgNew); // 拷贝图属性 DeepCopyOfBG(bgNew, oldBg); }
图属性深拷贝函数
void someFunction::DeepCopyOfBG(BGType* bGraph, BGType* oldBg) { // 遍历源图的_modInfo并拷贝内容 for (const auto& entry : (*bGraph)[boost::graph_bundle]._modInfo) { const std::string& key = entry.first; const auto& value = entry.second; // 创建value的深拷贝(包含schPinInfo*向量的元组) std::tuple<std::vector<schPinInfo*>, std::vector<schPinInfo*>, std::vector<schPinInfo*>> deepCopyValue = value; // 将深拷贝添加到目标图的_modInfo中 (*oldBg)[boost::graph_bundle]._modInfo[key] = deepCopyValue; } // 其他属性拷贝逻辑 }
解决方法
要实现_subGraph的深度拷贝,需在自定义顶点拷贝逻辑中递归创建并拷贝子图实例,同时修正_graph指针指向新的图实例。
1. 修改CustomVertexCopy结构体
更新顶点拷贝逻辑,对_subGraph进行递归深拷贝,同时修正_graph指针指向新图:
struct CustomVertexCopy { BGType const &g1; BGType &g2; void operator()(BGType::vertex_descriptor v1, BGType::vertex_descriptor v2) const { vertexProps const &p1 = g1[v1]; vertexProps &p2 = g2[v2]; // 拷贝基础属性 p2._moduleName = p1._moduleName; p2._name = p1._name; p2._refPtr = p1._refPtr; // 修正_graph指针:新顶点的_graph指向当前拷贝的新图 p2._graph = &g2; // 深度拷贝_subGraph if (p1._subGraph != nullptr) { // 创建新的子图实例 p2._subGraph = new BGType; // 递归调用copy_graph,复用自定义拷贝逻辑处理子图的顶点和边 boost::copy_graph( *p1._subGraph, *p2._subGraph, boost::vertex_copy(CustomVertexCopy{*p1._subGraph, *p2._subGraph}) .edge_copy(CustomEdgeCopy{*p1._subGraph, *p2._subGraph}) ); // 拷贝子图的图属性 boost::get_property(*p2._subGraph) = boost::get_property(*p1._subGraph); // 调用DeepCopyOfBG处理子图的额外自定义属性 DeepCopyOfBG(p1._subGraph, p2._subGraph); } else { p2._subGraph = nullptr; } } };
2. 补充内存管理逻辑
为避免内存泄漏,给vertexProps添加析构函数释放_subGraph资源:
class vertexProps { // ... 现有成员 ... ~vertexProps() { delete _subGraph; // 递归释放子图,子图的顶点会触发自身析构 } };
注意:如果存在循环引用(比如子图顶点的
_graph指向父图),需改用std::shared_ptr<BGType>代替裸指针,否则会导致析构时无限递归或内存泄漏。
3. 调整图属性拷贝逻辑
如果图属性中也存在指向自身的指针,需在DeepCopyOfBG中同步修正,确保新图的属性指向自身而非原实例。
内容的提问来源于stack exchange,提问作者tushar
相关产品推荐
相关产品推荐

