提升图是否正在切割我的 shared_ptr
Is boost graph slicing my shared_ptr
我正在使用带有 boost::shared_ptr<Obj>
作为边缘属性的增强图的实现。我有两个 class Obj
和 Obj2
这样:
class Obj{
public:
Obj(){};
virtual func(){std::cout << "Obj func " << std::endl};
};
class Obj2: public Obj{
public:
Obj2(){};
virtual func(){std::cout << "Obj2 func " << std::endl};
};
我正在使用(简化的)函数在图中添加边,例如:
void addEdge(Vertex index, Vertex index2, const boost::shared_ptr<Obj>& edgeAttribute){
out = boost::add_edge(index, index2, edgeAttribute, graph).first;
}
我调用使用:
Obj2* obj = new Obj2();
boost::shared_ptr<Obj2> obj_ptr(obj);
addEdge(index, index2, obj_ptr);
但是稍后在我的代码中,当通过 edgeAttr = graph[edge]
获取边缘属性然后调用函数 edgeAttr->func()
时,我调用了 Obj 的 func 而不是 Obj2 的。
据我了解,这意味着我的对象在某处被切片。我给出的这个简短示例是否应该在使用 boost:shared_ptr 和 BGL 时对我的对象进行切片,还是我自己的一些其他实现问题,如初始化?
不,图模型不对任何属性进行切片(请注意,"attribute" 实际上称为捆绑 属性)。
事实上,它从不复制 Obj
或 Obj2
因为它只是复制导致共享所有权的 shared_ptr<>
,因为反对复制 属性.
让我们来演示一下它是如何工作的
#include <boost/graph/adjacency_list.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/make_shared.hpp>
#include <iostream>
class Obj {
public:
Obj(){};
virtual void func(std::ostream& os) { os << "Obj func\n"; };
};
class Obj2 : public Obj {
public:
Obj2(){};
virtual void func(std::ostream& os) { os << "Obj2 func\n"; };
};
// I'm adding edges in the graph using a (simplified) function such as:
using Graph = boost::adjacency_list<boost::vecS, boost::vecS,
boost::directedS, boost::no_property, boost::shared_ptr<Obj> >;
using Vertex = Graph::vertex_descriptor;
struct Program {
Program() : _graph(10) {}
void addEdge(Vertex index, Vertex index2, const boost::shared_ptr<Obj> &edgeAttribute) {
auto out = boost::add_edge(index, index2, edgeAttribute, _graph).first;
}
void sample_edges() {
Obj2 *obj = new Obj2();
boost::shared_ptr<Obj2> obj_ptr(obj);
addEdge(1, 2, boost::make_shared<Obj2>());
addEdge(2, 3, boost::make_shared<Obj >());
addEdge(3, 4, boost::make_shared<Obj2>());
addEdge(4, 5, boost::make_shared<Obj >());
addEdge(5, 6, boost::make_shared<Obj2>());
addEdge(6, 7, boost::make_shared<Obj >());
}
void debug_dump() const {
for (auto ed : boost::make_iterator_range(boost::edges(_graph))) {
_graph[ed]->func(std::cout << "Edge " << ed << ": ");
}
}
private:
Graph _graph;
};
int main() {
std::cout << "Demo edges:\n";
Program demo;
demo.sample_edges();
demo.debug_dump();
std::cout << "Copied edges:\n";
// copy the whole shebang
Program clone = demo;
clone.debug_dump();
}
打印:
Demo edges:
Edge (1,2): Obj2 func
Edge (2,3): Obj func
Edge (3,4): Obj2 func
Edge (4,5): Obj func
Edge (5,6): Obj2 func
Edge (6,7): Obj func
Copied edges:
Edge (1,2): Obj2 func
Edge (2,3): Obj func
Edge (3,4): Obj2 func
Edge (4,5): Obj func
Edge (5,6): Obj2 func
Edge (6,7): Obj func
我正在使用带有 boost::shared_ptr<Obj>
作为边缘属性的增强图的实现。我有两个 class Obj
和 Obj2
这样:
class Obj{
public:
Obj(){};
virtual func(){std::cout << "Obj func " << std::endl};
};
class Obj2: public Obj{
public:
Obj2(){};
virtual func(){std::cout << "Obj2 func " << std::endl};
};
我正在使用(简化的)函数在图中添加边,例如:
void addEdge(Vertex index, Vertex index2, const boost::shared_ptr<Obj>& edgeAttribute){
out = boost::add_edge(index, index2, edgeAttribute, graph).first;
}
我调用使用:
Obj2* obj = new Obj2();
boost::shared_ptr<Obj2> obj_ptr(obj);
addEdge(index, index2, obj_ptr);
但是稍后在我的代码中,当通过 edgeAttr = graph[edge]
获取边缘属性然后调用函数 edgeAttr->func()
时,我调用了 Obj 的 func 而不是 Obj2 的。
据我了解,这意味着我的对象在某处被切片。我给出的这个简短示例是否应该在使用 boost:shared_ptr 和 BGL 时对我的对象进行切片,还是我自己的一些其他实现问题,如初始化?
不,图模型不对任何属性进行切片(请注意,"attribute" 实际上称为捆绑 属性)。
事实上,它从不复制 Obj
或 Obj2
因为它只是复制导致共享所有权的 shared_ptr<>
,因为反对复制 属性.
让我们来演示一下它是如何工作的
#include <boost/graph/adjacency_list.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/make_shared.hpp>
#include <iostream>
class Obj {
public:
Obj(){};
virtual void func(std::ostream& os) { os << "Obj func\n"; };
};
class Obj2 : public Obj {
public:
Obj2(){};
virtual void func(std::ostream& os) { os << "Obj2 func\n"; };
};
// I'm adding edges in the graph using a (simplified) function such as:
using Graph = boost::adjacency_list<boost::vecS, boost::vecS,
boost::directedS, boost::no_property, boost::shared_ptr<Obj> >;
using Vertex = Graph::vertex_descriptor;
struct Program {
Program() : _graph(10) {}
void addEdge(Vertex index, Vertex index2, const boost::shared_ptr<Obj> &edgeAttribute) {
auto out = boost::add_edge(index, index2, edgeAttribute, _graph).first;
}
void sample_edges() {
Obj2 *obj = new Obj2();
boost::shared_ptr<Obj2> obj_ptr(obj);
addEdge(1, 2, boost::make_shared<Obj2>());
addEdge(2, 3, boost::make_shared<Obj >());
addEdge(3, 4, boost::make_shared<Obj2>());
addEdge(4, 5, boost::make_shared<Obj >());
addEdge(5, 6, boost::make_shared<Obj2>());
addEdge(6, 7, boost::make_shared<Obj >());
}
void debug_dump() const {
for (auto ed : boost::make_iterator_range(boost::edges(_graph))) {
_graph[ed]->func(std::cout << "Edge " << ed << ": ");
}
}
private:
Graph _graph;
};
int main() {
std::cout << "Demo edges:\n";
Program demo;
demo.sample_edges();
demo.debug_dump();
std::cout << "Copied edges:\n";
// copy the whole shebang
Program clone = demo;
clone.debug_dump();
}
打印:
Demo edges:
Edge (1,2): Obj2 func
Edge (2,3): Obj func
Edge (3,4): Obj2 func
Edge (4,5): Obj func
Edge (5,6): Obj2 func
Edge (6,7): Obj func
Copied edges:
Edge (1,2): Obj2 func
Edge (2,3): Obj func
Edge (3,4): Obj2 func
Edge (4,5): Obj func
Edge (5,6): Obj2 func
Edge (6,7): Obj func