C++构造函数中为类属性赋值ListDigraph::ArcMap的问题
问题分析与解决方案
问题原因
LEMON库中的ArcMap(包括NodeMap等映射类)的赋值运算符operator=被设为私有,不支持直接赋值操作。这类映射与所属的图对象强绑定,设计上就不允许通过赋值来变更关联的图或替换映射实例,所以你在构造函数中执行this->length = ListDigraph::ArcMap<int>(g);会触发报错。
解决方法
1. 用构造函数初始化列表直接初始化映射
这是最规范且简单的方式,在类的构造函数初始化列表中直接调用ArcMap的构造函数,将其与类内的图对象绑定,避免后续的赋值操作:
class GraphHandler { public: ListDigraph g; ListDigraph::ArcMap<int> length; // 初始化列表中直接初始化length,绑定到g GraphHandler() : length(g) {} };
这种方式会在对象创建时直接完成length的初始化,完全符合你的需求——随对象创建生成映射,且能在类的其他成员函数中修改映射的值(比如length[arc] = 10;这类操作是允许的)。
2. 若需后期更换关联的图
如果后续需要替换类内的图对象并重新绑定映射,不能直接赋值length,可以使用ArcMap的swap方法来交换新映射的内部数据:
void replaceGraph() { // 创建新的图对象和对应的映射 ListDigraph newG; ListDigraph::ArcMap<int> newLength(newG); // 替换类内的图和映射 g.swap(newG); length.swap(newLength); }
这样既完成了图的替换,也让length重新关联到新的图对象,同时避免了禁用的赋值操作。
注意事项
ArcMap的生命周期必须与它绑定的图对象保持一致,不能在图对象销毁后继续使用对应的映射,否则会导致未定义行为。- 类内的
g和length作为成员变量,在类的任意成员函数中修改它们的状态(比如添加节点/边、修改映射值)都会直接改变对象的全局状态,满足你的需求。
内容的提问来源于stack exchange,提问作者Claudio Tomasi
相关产品推荐
相关产品推荐

