• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 186
  • Last Modified:

Question on pointers

     I have arrays of pointers given by:
           static Node * nodeArray = NULL;
           static Edge * edgeArray = NULL;
     and I initialized the arrays as :
           nodeArray = new Node[<some integer>];
           edgeArray = new Edge[<some integer>];

     I defined the 'Edge' class like this:
#include "Node.cpp"
class Edge
                Edge(Node &N1, Node &N2);
                Node *leftNode;
                Node *rightNode;
                float length;
                bool isIncluded;
Edge::Edge(Node &N1, Node &N2)
        isIncluded = false;
        leftNode = &N1;
        rightNode = &N2;
        length = N1.distanceTo(N2);

When I am trying to create an instance of 'Edge' in the edgeArray like this:

     edgeArray[<some integer>] = new Edge(nodeArray[xCount],nodeArray[yCount]);

I am getting an error saying that:

     no match for `Edge& = Edge*&' operator
     Edge.cpp:5: candidates are: Edge& Edge::operator=(const Edge&)

I am not able to figure out what went wrong in my code. I would appreciate if you can help me in this.

1 Solution
you must alloc the pointer like this:
edgeArray = new Edge(nodeArray[xCount],nodeArray[yCount]);
this is how you alloc heap memory for an Edge object.the overloaded constructor will be called for this object.

If you want to alloc a dynamic array:
edgeArray = new Edge[<some integer>];
in this you created a dynamic array with <some integer> Edge objects. also the default constructor will be called for each object.
you have declared an array of edges not an array of     Edge *'s.  new returns a pointer.

static Edge * edgeArray = new Edge[<some integer>];
should be perhaps

static Edge ** edgeArray = new Edge*[<some integer>];

this compiles fine

int main()

    static Edge * edgeArray = 0;
    edgeArray = new Edge[5];
    Node x, y;
    edgeArray[0] = Edge(x, y);
    return 0;

as does this

int main()

    static Edge ** edgeArray = 0;
    edgeArray = new Edge*[5];
    Node x, y;
    edgeArray[0] = new Edge(x, y);
    return 0;

However in the first implementation you are doing a copy of the Edge(x, y) , since you are using pointers you probably should create a copy construtor, an = operator and a destructor... which I can post if necessary.
First off:

new Edge(....);

Returns a pointer to an Edge (type is Edge *) you cannot store that into an Edge unless you have an assignment operator that allow that. You probably won't want that since you want the data stored.

Since creating an array of edges makes all the edges with default constructor you need to set the value through some other way.

So, you don't need that Edge(Node & N1, Node & N2) constructor of yours, just dump it.

You do need a function like this though:

void Edge::Connect(Node & N1, Node & N2)
   ....connect node N1 and N2 to edge.

That function should probably not only set the Node pointers in Edge but also set the Edge pointer in Node if you have any. This function will modify the edge and should only be called when you build up the structure or when you want to rearrange the structure of the nodes.

If you want to make sure that other code cannot call Connect you must limit the access to it one way or the other. One way would be to put it private in Edge and make "Node" or "GraphBuilder" or some such class a friend class of Edge. A GraphBuilder class would then be the class that cuild build the graph and only that class could access that function. Such a class if friend can actually access any private member of Edge but since it is limited to GraphBuilder you can probably live with that.

If you cannot then you must make a two-layer encapsulation:

class RealEdge {
   Node * .....; blah blah blah
   void COnnect(Node & N1, Node & N2);

And then make an Edge class like this:

class Edge {
   RealEdge e;

   friend class GraphBuilder;
   void foo() { e.foo(); }
   int bar(int k) { return e.bar(k); }

Now, the Edge class give unlimited access to its member RealEdge to GraphBuilder but as that is itself a class the Graphbuilder really only have access to the public funcitons and to the function Connect() which it should. The private data of RealEdge are not accessible - not even to GraphBuilder.

Hope this is of help for you.

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Mayank SAssociate Director - Product EngineeringCommented:
>> edgeArray = new Edge[<some integer>];

Here, you have already allocated memory for, say, n objects (if <some integer> = n). So you don't need to allocate memory for them once again (which is probably what you are trying to do by writing:

>> edgeArray[<some integer>] = new Edge(nodeArray[xCount],nodeArray[yCount]);

It is not needed as the object in that position of the array has already been allocated memory and it has been initialized using the default constructor.

Moreover, 'new' will allocate memory for the object and return its address, so you cannot assign it to an object but you need to assign it to a pointer. Then your 'edgeArray' will need to be an array of pointers.

As a minimal change for your code to work, all you need to do is modify the line:
 edgeArray[<some integer>] = new Edge(nodeArray[xCount],nodeArray[yCount]);
edgeArray[<some integer>] = Edge(nodeArray[xCount],nodeArray[yCount]);

You should only call 'new' when you want a heap-allocated object. The corrected line above will create a temporary Edge instance, then copy it into the item at index <some integer> in the array (which is already allocated).

This is the simplest approach in terms of memory management. (to make it even easier, you could use a standard library collection such as std::deque<T> instead of an array).

The problem with that is that he then construct an Edge object with the default constructor, before assigning over he must first properly close that object.

Assuming that the default constructor won't assign any pointers to any non-NULL value etc might help in this.

A worse problem is that you have to make an assignment operator and that assignment operator has to work even if the object at first isn't a "null object" created by a default constructor.

I would rather suggest you dump the extra constructor you don't need and rather create a GraphBuilder class that is made friend to all the important classes and can construct the structure the way you want it. Then you use the GraphBuilder when you want to create the Graph and all constructors to Edge and Node objects should then be made private and GraphBuilder should be friend so only GraphBuilder can create those objects.

Other classes only use references and pointers to those objects, never create any actual objects on their own.

This is the safest approach I think.


Featured Post

Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now