1

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 object

the 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:)

Matthieu M.
  • 287,565
  • 48
  • 449
  • 722
LoveTW
  • 3,746
  • 12
  • 42
  • 52

3 Answers3

5

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.

Community
  • 1
  • 1
Armen Tsirunyan
  • 130,161
  • 59
  • 324
  • 434
  • Graph g; => g is a Graph object ; Graph g* = new Graph() => g is a pointer point to g* ; I can use &g to get the address of g* (Is my understanding right?) Thanks:) – LoveTW Mar 05 '12 at 16:58
1

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.

Benoit
  • 76,634
  • 23
  • 210
  • 236
1

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.

James Kanze
  • 150,581
  • 18
  • 184
  • 329
  • If i add g[vid] in get_forward_root, this is an object? Why i have to use Vertex &v = g[vid] not Vertex *v = g[vid]? Thanks:) – LoveTW Mar 05 '12 at 17:22
  • `g[vid]` is an expression. It returns a reference, in other words, and alias for an element in the vector. It's not a pointer, so you can't assign it to a pointer. (Most of the time, you'd probably just write `Vertex v = g[vid]`, and define an object.) – James Kanze Mar 05 '12 at 18:49
  • Thanks for your advisement! But this sample code is from the author of gSpan, he use `&v = g[vid]` not `v = g[vid]`, do you know the purpose? Thanks:) – LoveTW Mar 06 '12 at 02:12
  • I want to ask another question: `Graph g;` => `g` is a Graph object ; `Graph g* = new Graph();` => `g` is a pointer point to `g*` ; I can use `&g` to get the address of `g*` (Is my understanding right?) Thanks:) – LoveTW Mar 06 '12 at 02:16
  • @Mr.mr. How is `v` defined? I can't think of any type that `v` could have where `&v = g[vid]` would compile. Are you sure you don't mean `Vector &v = g[vid];`: this defines a reference to the element in `g`. – James Kanze Mar 06 '12 at 09:25
  • @Mr.mr. `Graph g* = new Graph();` won't compile. It's not legal C++. – James Kanze Mar 06 '12 at 09:26