c++ - boost 图是否正在切片我的 shared_ptr

标签 c++ boost graph shared-ptr object-slicing

我正在使用带有 boost::shared_ptr<Obj> 的 boost 图的实现作为边缘属性。我有两个类(class) ObjObj2这样:

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

我称之为 using :

Obj2* obj = new Obj2();
boost::shared_ptr<Obj2> obj_ptr(obj);
addEdge(index, index2, obj_ptr);

但是稍后在我的代码中通过执行 edgeAttr = graph[edge] 获取边缘属性时然后调用函数 edgeAttr->func() ,我调用 Obj 的函数而不是 Obj2 的。

据我了解,这意味着我的对象在某处被切片。我给出的这个简短示例是否应该在使用 boost:shared_ptr 和 BGL 时对我的对象进行切片,还是我自己的一些其他实现问题,如初始化?

最佳答案

不,图模型不对任何属性进行切片(请注意,“属性”实际上称为捆绑属性)。

事实上,它从不复制 ObjObj2因为它只是复制 shared_ptr<>导致共享所有权,而不是复制属性。

让我们来演示一下它是如何工作的

Live On Coliru

#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

关于c++ - boost 图是否正在切片我的 shared_ptr,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47946265/

相关文章:

c++ - 服务器和多个客户端使用 pthreads 和 select()

c++ - 类方法访问它的数据成员

class - 可以将 boost::program_options 与自己的模板类一起使用吗?

python - 如何连接字典中文本的连续单词?

java - 使用 PriorityQueue 的 NullPointerException

c++ - 创建图c++的逻辑

c++ - std::aligned_storage 中的新位置?

c++ - 使用 cin.clear() 之间的区别;

c++ - 可以将 boost 累加器用作类成员

c++ - Boost单元测试框架: How to show a per test suite message