We need to create a new access object. The header file is just like before (showing us how simple it is to create these):
class ACCESS_GRAPH : public ACCESS_VOID
{
public:
ACCESS_GRAPH(){;};
~ACCESS_GRAPH(){;};
int equal(Arbent,Arbent);
ostream& show(ostream&,Arbent);
void entry(Arbent *,Arbent);
};
However, we do have to write the new access methods. We don't really need to implement the equal method as we currently aren't checking for the equality of graphs.
//ACCESS_GRAPH
int ACCESS_GRAPH::equal(Arbent a,Arbent b)
{
}
However, the entry method is very interesting. A first attempt might be to try this:
void ACCESS_GRAPH::entry(Arbent *a,Arbent b)
{
//cast incoming data to proper type
cout << "Cast incoming data to proper type" << endl;
//Graph *T = (Graph *)b;
//grab colors
Pixel graph_colors[4];
graph_colors[0] = T->node_inside_color;
graph_colors[1] = T->node_border_color;
graph_colors[2] = T->edge_inside_color;
graph_colors[3] = T->edge_border_color;
//construct a graph
cout << "Construct a new Graph" << endl;
(Graph *)a = new Graph(T->edge_access,
T->node_access,
T->node_radius,
T->node_center,
T->foreground_color,
T->background_color,
graph_colors,
T->display,
T->drawable,
T->pixmap,
T->pixmap2,
T->gc);
cout << "Finished Constructing the new Graph" << endl;
cout << "Assign node pointer bag" << endl;
((Graph *)(*a))->d_nodes = T->d_nodes;
cout << "Assign edge pointer bag" << endl;
((Graph *)(*a))->d_edges = T->d_edges;
}
However, this will fail as all of these data fields are private in scope here and we cannot read them within the ACCESS_GRAPH class. It is not a wise solution to add friend status of ACCESS_GRAPH to the Graph class itself, so we must come up with another way. Looking at the Graph class code, note that we defined a copy constructor but never implemented it. That is exactly what we need for this to work. Here is the correct entry method code:
void ACCESS_GRAPH::entry(Arbent *a,Arbent b)
{
//cast incoming data to proper type
cout << "Cast incoming data to proper type" << endl;
//Graph *T = (Graph *)b;
cout << "Construct a new Graph" << endl;
(Graph *)(*a) = new Graph( *(Graph *)b );
}
and we add the Graph::Graph(const Graph& b) implementation below to the graph class implementation file graph.c.
Graph::Graph(const Graph& b)
{
cout << "In Graph copy constructor" << endl;
d_nodes = b.d_nodes;
d_edges = b.d_edges;
//cout << "finished with pointer bags " << endl;
foreground_color = b.foreground_color;
background_color = b.background_color;
node_inside_color = b.node_inside_color;
node_border_color = b.node_border_color;
edge_inside_color = b.edge_inside_color;
edge_border_color = b.edge_border_color;
display = b.display;
drawable = b.drawable;
gc = b.gc;
pixmap = b.pixmap;
pixmap2 = b.pixmap2;
node_radius = b.node_radius;
node_access = b.node_access;
edge_access = b.edge_access;
node_center.x = b.node_center.x;
node_center.y = b.node_center.y;
}
Now upon compiling, this code will fail due to the lines
d_nodes = b.d_nodes; d_edges = b.d_edges;
because these lines call the overloaded = for the GnodePtrBag and GedgePtrBag class respectively. These are private to those classes, so we will alter the definition of the GnodePtrBag and GedgePtrBag classes to make these public: the altered code is
class GedgePtrBag{
friend GedgePtrBagIter;
friend GedgePtrBagManip;
private:
GedgePtrBagLink *d_root_p;
//GedgePtrBag(const GedgePtrBag&); <== move to public
//GedgePtrBag& operator=(const GedgePtrBag&); <== move to public
public:
GedgePtrBag();
GedgePtrBag(const GedgePtrBag&);
GedgePtrBag& operator=(const GedgePtrBag&);
~GedgePtrBag();
void add(Gedge *pointer);
void removeAll(const Gedge *pointer);
};
with a similar change to the GNodePtrBag class. With these changes, the code will compile.
Finally, the show method simply calls the existing graph methods via our usual overloaded ostream operator.
ostream& ACCESS_GRAPH::show(ostream& out, Arbent a)
{
cout << endl << " Output Access Graph " << endl;
Graph *t = (Graph *)a;
out << *((Graph *)a) << endl;
return out;
}