Factory for constructing directed graphs in C++ I want to implement a directed graph which has 3 main kind of edges:


self referencing edges
non directional edges between two nodes
directional edges between two nodes




Also I want to be able to do global operations on the graph, like e.g. counting or removing all edges fulfilling certain criteria.

The easiest program structure I came up with is:

#include &lt;unordered_set&gt;

using namespace std;

struct Edge;

struct Node
{
    Node(std::string name):name(name){}
    string name;
    std::unordered_set&lt;Edge*&gt; edges;
};

struct Edge
{
    Edge(Node * node1): node1(node1){}
    double weight;
    Node * node1;
};

struct EdgeBetweenTwoNodes: public Edge
{
    EdgeBetweenTwoNodes(Node * node1, Node * node2 ): Edge(node1), node2(node2){}
    Node * node2;
};

struct DirectionalEdge: public EdgeBetweenTwoNodes
{
    DirectionalEdge(Node * node1, Node * node2, bool direction ): EdgeBetweenTwoNodes(node1,node2), direction(direction){}
    bool direction;
};

struct EdgesContainer
{
    std::unordered_set&lt;Edge*&gt; all_edges;

    void register_new_edge(Edge * edge)
    {
        all_edges.insert(edge);
    }

    //do all kind of manipulations on all edges of a cetain type...
};


struct EdgeFactory
{
    EdgeFactory(){}

    void create_edge(Node* node1,EdgesContainer &amp; edge_container)
    {
        Edge * edge = new Edge(node1);
        node1-&gt;edges.insert(edge);

        edge_container.register_new_edge(edge);
    }

    void create_edge(Node* node1, Node* node2, EdgesContainer &amp; edge_container)
    {
        EdgeBetweenTwoNodes * edge = new EdgeBetweenTwoNodes(node1,node2);
        node1-&gt;edges.insert(edge);
        node2-&gt;edges.insert(edge);

        edge_container.register_new_edge(edge);
    }

    void create_edge(Node* node1, Node* node2, bool direction, EdgesContainer &amp; edge_container)
    {
        DirectionalEdge * edge = new DirectionalEdge(node1,node2,direction);
        node1-&gt;edges.insert(edge);
        node2-&gt;edges.insert(edge);

        edge_container.register_new_edge(edge);
    }
};


int main()
{
    Node * A = new Node("A");
    Node * B= new Node("B");
    Node * C= new Node("C");

    EdgesContainer edges;

    EdgeFactory edge_factory;
    edge_factory.create_edge(A,edges);
    edge_factory.create_edge(A,B,edges);
    edge_factory.create_edge(A,C,1,edges);

    return 0;
}


What do you think about it? Is this the correct use of a so called "Factory?"
Don't use using namespace std; it pollutes the namespace and creates name collisions. Only do this with concrete classes and only within a namespace or cpp file.



new without delete => leaks. Instead use smart pointers or store them by value where it makes sense. 



There is no need to create a class hierarchy for the edges, instead use a enum to differentiate: enum{BIDIR, FROM_1_TO_2, FROM_2_TO_1} and a self referential edge is a BIDIR and nodes 1 and 2 are equal.

unordered_set is far from the best data structure, it's slow to iterate over, access is very often a cache miss or two. Instead prefer data structures like std::vector where it is very fast to iterate over.

The best data structure depends a lot on what operations you will be doing on it, which you didn't mention so I can't really judge beyond saying that unordered_set is most likely a bad choice.