Reputation: 3832
I have read the topic about "pointer", but i still have some question.
// graph.cpp
struct Edge {
int from;
int to;
unsigned int id;
Edge(): from(0), to(0), id(0) {};
};
struct Vertex {
int label;
vector<Edge> edge;
};
class Graph: public vector<Vertex> {
int gid;
unsigned int edge_size;
};
if I declare a iterator in another file
bool get_forward_root (Graph &g, Vertex &v, vector<Edge*> &result) {
for(vector<Edge>::iterator it = v.edge.begin(); it != v.edge.end(); it++) {
if(v.label <= g[it->to].label)
result.push_back(&(*it));
}
}
In my understanding, it
can be viewed as pointer, since v.edge.begin()
is the first Edge
object in vector<Edge>
, but what is &(*it)
?
Question 2. What is the difference between g
, &g
, *g
?
In my understanding:
&g
is the memory address.*g
is a Graph pointer point to a graph object, so we can use Graph *g = new Graph();g
is a Graph objectthe difference between *g and g is how we use, for example the two conditions are the same:
condition 1:
Graph *g = new Graph();
g->gid = 0;
condition 2:
Graph g;
g.gid = 0;
Question 3.
what is below meaning?
Graph &g
and why we use g[it->to].label
not &g[it->to].label
Thank very much:)
Upvotes: 1
Views: 233
Reputation: 153929
Question 1: it
is not a pointer, it is an iterator. Iterators behave
somewhat like pointers, for certain things only, but they aren't
pointers. In the expression &(*it)
, *
dereferences the iterator, to obtain
a reference to the actual object it designates; the &
then takes the
address of this object, which results in an actual pointer, with pointer
type (which is what the container result
requires).
Question 2: g
is the name of an object; in an expression, it
designates the object, and has the type of the object. &g
is the
address of the object; an object in itself (albeit temporary) with a
pointer type. *g
isn't legal. At least as long as no user defined
operators come into play: the type Graph
could overload operator*
or
operator&
to do more or less anything. (Given the example, with
g[it->to]
, it is clear that Graph
overloads []
; this means that
the usual identity a[b]
means *(a+b)
doesn't hold.) And in your
code, g
is not a pointer to a Graph
, it is a reference, which acts
like an alias—another name for whatever it was initialized with.
With regards to Graph* g
and Graph g
: there is a vital difference in
the lifetime of the objects (or in the case of Graph* g
, the lifetime
of the pointed to object).
Question 3: The Graph& g
has no relationship with the operator &
; it
is a means of telling the compiler that g
is a reference. A reference
is fundamentally just another name for the initialing object (or the
only name, if the initializing object doesn't have a name otherwise).
References are mostly (but not exclusively) used as function parameters.
Upvotes: 1
Reputation: 133024
Question 1: what is &(*it)
it
acts like a pointer, but it's not a pointer. If it were a pointer, &*it
would be the same as it
. In the general case, &(*it)
is the address (a real pointer) of the object that the iterator it
points to. We can assume here that the & operator was not overloaded.
Question 2: What is the difference between g, &g, *g?
g
is g
. &g
is the address of g. *g
is the object g
points to (if g is a pointer). Your 2 conditions (I don't understand why you call them conditions) do pretty much the same thing, yes.
Question 3: what is
Graph &g?
It's called a reference. When defined, it should be immediately initialized. Think of a reference as another name of an object. (Better, read a book, see below).
All of your questions will be thoroughly answered in any decent C++ beginner book. I especially recommend Lippman's C++ primer for this purpose. Find other good titles here.
Upvotes: 5
Reputation: 79185
it
is not a pointer, it is an iterator. Basically it behaves like a pointer (dereference and arrow operators are overloaded) and also like an array index (++
, --
, +=
, etc. advance the iterator to point to the next element. For vectors you may find that useless, but that's great for other containers).
So, &(*it)
transforms the iterator into a real pointer: it takes the address of the pointed-to object. It does not make much of a difference on a vector though, because all elements are stored into contiguous memory areas.
Upvotes: 1