Inside your Graph class, the gph member is a std::vector containing std::vector elements. std::vector is a wrapper for new[] and delete[], so there is no need to use them directly to allocate the vectors. To change a std::vector's size at runtime, you can use its resize() method instead, eg:
class Graph {
private:
vector< vector<int> > gph;
public:
explicit Graph(int size=50) {
gph.resize(size);
for (int i = 0; i < size; ++i)
gph[i].resize(size);
}
/* You can even reduce the constructor even more,
using the constructor initialization list, if you
don't mind a little extra overhead temporarily...
explicit Graph(int size=50)
: gph(size, std::vector<int>(size) ) {
}
*/
/* not necessary to clear the vector during destruction,
it is handled automatic by the vector's own destructor...
~Graph() {
retgph();
}
*/
void retgph() {
gph.clear();
}
int getLength(int x, int y) {
return gph[x][y];
}
void setGraph(int x, int y, int value) {
gph[x][y] = value;
}
};
As for the rest off your code...
The new operator returns a pointer to a newly instantiated object that is allocated on the heap. So new Graph allocates a Graph object, calls the Graph() constructor on it, and returns a Graph* pointer to that object.
Your compiler error is because your abc variable is declared as a Graph instantiated object on the stack instead of a Graph* pointer. So, when you call abc = ..., you are actually calling the Graph::operator=() copy assignment operator (which in this case is auto-generated by the compiler for you). That operator expects a const Graph& (reference to a constant Graph object) as input, not a Graph* (pointer to a Graph object), thus the "no known conversion from Graph* to const Graph&" compiler error.
Same thing for your opn variable, using the Open class.
Change the abc and opn variables into pointers, and change any . to -> when accessing methods of those objects. And don't forget to delete the objects when you are done using them:
int main() {
const int size = 10;
Graph *abc; // pointer to graph object.
Open *opn; // pointer to open set object.
abc = new Graph(size);
opn = new Open(size);
//...
abc->setGraph(x, y, value);
opn->doSomething(parameters);
//...
delete opn;
delete abc;
}
Or, use a std::auto_ptr or std::unique_ptr to handle the delete for you:
#include <memory>
int main() {
const int size = 10;
std::uninque_ptr<Graph> abc( new Graph(size) );
std::unique_ptr<Graph> opn( new Open(size) )
//...
abc->setGraph(x, y, value);
opn->doSomething(parameters);
//...
}
Or, just keep instantiating them on the stack, but get rid of new and delete, and let them destruct themselves when they go out of scope when main() exits:
int main() {
const int size = 10;
Graph abc(size);
Open opn(size);
//...
abc.setGraph(x, y, value);
opn.doSomething(parameters);
//...
}
Now, to answer your questions:
I think ABC =NEW GRAPH(50) should instantiate an object ABC but the graph is built in the constructor Graph(int= size) and is GPH.
abc = new Graph(50) instantiates a new Graph object with a constructor value of 50, and then assigns that object pointer to abc. Internally, the Graph constructor instantiates the gph vectors using the specified size.
What graph am I accessing when I say ABC.setNodeValue(1,2,3); ? The graph GPH in the class or another ABC instantiated?
You are accessing the abc object, which internally accesses the gph vectors.
If it is the one instantiated (ABC) why does GPH appear in the class Graph at all?
It is a piece of data that is inside of the abc object. Think of Graph as an envelope, and gph as a thing inside of the envelope, and abc as the hand that is holding the envelope. Each time new Graph is called, a new envelope is created with a new gph inside of it.
My thinking is that ABC is the one that will be manipulated by the methods (ABC.getNodeValue(47);) .
Yes.
Does GPH in the class just appear there as a model for the instantiation process?
No. It is one of the things being instantiated.
Also GPH is actually INT **GPH;`
Not in the code you have shown. But logically, that is equivalent to how a 2-dimensional std::vector behaves at runtime - a pointer (inside the outer vector) to a dynamic array (what the outer vector manages) of pointers (the inner vectors) to dynamic arrays (what the inner vectors manage) of integers (what the inner vectors hold).
The C equivalent of the above code would look something like this:
struct Graph {
int size;
int **gph;
};
struct Open {
//...
};
Graph* createGraph(int size=50) {
Graph *g = (Graph*) malloc(sizeof(Graph));
g->size = size;
g->gph = (int**) malloc(sizeof(int**) * size);
for (int i = 0; i < size; ++i)
gph[i] = (int*) malloc(sizeof(int) * size);
return g;
}
Open* createOpen(int size=50) {
Open *o = (Open*) malloc(sizeof(Open));
//...
return o;
}
void retGraph(Graph *g) {
for (int i = 0; i < g->size; ++i)
free(gph[i]);
free(g->gph);
g->gph = NULL;
g->size = 0;
}
void freeGraph(Graph* g) {
retGraph(g);
free(g);
}
void freeOpen(Open* o) {
//...
free(o);
}
int getLength(Graph *g, int x, int y) {
return g->gph[x][y];
}
void setGraph(Graph *g, int x, int y, int value) {
g->gph[x][y] = value;
}
void doSomething(Open *o, parameters) {
//...
}
int main() {
const int size = 10;
Graph *abc = createGraph(size);
Graph opn = createOpen(size)
//...
setGraph(abc, x, y, value);
doSomething(opn, parameters);
//...
freeOpen(opn);
freeGraph(abc);
}
*abc = new Graph(size);and*opn = new Open(size);.gphis a vector, not aint**. Don'tnewup memory for it.Graph*to aGraphvalue.newin c++ is equivalent ofmallocin c with some extra features. And asmallockit returns pointer. And you can not assign pointer type to not pointer type.