?
Solved

Question on pointers

Posted on 2003-03-19
6
Medium Priority
?
185 Views
Last Modified: 2010-04-01
Hi..
     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
{
        public:
                Edge();
                Edge(Node &N1, Node &N2);
                Node *leftNode;
                Node *rightNode;
                float length;
                bool isIncluded;
};
Edge::Edge()
{
}
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.

Thanks,
SJ.
0
Comment
Question by:sj1187534
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
6 Comments
 
LVL 3

Expert Comment

by:cmaryus
ID: 8172137
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.
0
 
LVL 1

Expert Comment

by:frogger1999
ID: 8172202
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.
0
 
LVL 12

Expert Comment

by:Salte
ID: 8173887
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 {
private:
   Node * .....; blah blah blah
public:
   void COnnect(Node & N1, Node & N2);
};

And then make an Edge class like this:

class Edge {
private:
   RealEdge e;

   friend class GraphBuilder;
public:
   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.

Alf
0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
LVL 30

Expert Comment

by:Mayank S
ID: 8179355
>> 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.

Mayank.
0
 
LVL 1

Accepted Solution

by:
ivec earned 150 total points
ID: 8181697
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]);
To:
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).

0
 
LVL 12

Expert Comment

by:Salte
ID: 8181888
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.

Alf
0

Featured Post

[Webinar] How Hackers Steal Your Credentials

Do You Know How Hackers Steal Your Credentials? Join us and Skyport Systems to learn how hackers steal your credentials and why Active Directory must be secure to stop them.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Written by John Humphreys C++ Threading and the POSIX Library This article will cover the basic information that you need to know in order to make use of the POSIX threading library available for C and C++ on UNIX and most Linux systems.   [s…
Container Orchestration platforms empower organizations to scale their apps at an exceptional rate. This is the reason numerous innovation-driven companies are moving apps to an appropriated datacenter wide platform that empowers them to scale at a …
The viewer will learn how to user default arguments when defining functions. This method of defining functions will be contrasted with the non-default-argument of defining functions.
The viewer will learn how to clear a vector as well as how to detect empty vectors in C++.
Suggested Courses

762 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question