Daloupe
Daloupe

Reputation: 167

How is x = &(*variable) different from x = variable?

I've been trying to understand c++ by going over some projects and i came across this:

vector<Circle>::iterator circleIt = mCircles.end();
..
mCurrentDragCircle = &(*circleIt);

Why would you dereference and then reference it again?

Upvotes: 1

Views: 105

Answers (4)

Nimelrian
Nimelrian

Reputation: 1716

The *-operator is overloaded for the iterator class. It doesn't do a simple dereference. Instead, it returns a reference to the variable it's currently pointing at. Using the reference operator on this returns a pointer towards the variable.

Using mCurrentDragCircle = circleIt; would assign the iterator to your field.

Upvotes: 5

Fred Foo
Fred Foo

Reputation: 363567

circleIt is an iterator, and iterators overload operator* so that they look like pointers. Dereferencing an iterator gives a reference to the value; & turns that into a pointer to the value. So this is converting an iterator to a pointer.

Btw., dereferencing past-the-end, i.e. *v.end(), has undefined behavior. The proper way to do this is

v.data() + v.size()

in C++11, or

&v[0] + v.size()

in C++98. Both assume the vector is non-empty.

Upvotes: 5

Bathsheba
Bathsheba

Reputation: 234695

&* is a particularly pernicious idiom for extracting an underlying pointer. It's frequently used on objects that have an overloaded dereference operator *.

One such class of objects are iterators. The author of your class is attempting to get the address of the underlying datum for some reason. (Two pitfalls here, (i) *end() gives undefined behaviour and (ii) it appears that the author is storing the pointer value; blissfully unaware that modifications on that container could invalidate that value).

You can also see it used with smart pointers to circumvent reference counting.

My advice: avoid if at all possible.

Upvotes: 2

graywolf
graywolf

Reputation: 7490

Because of how iterators works.

*circleIt

will return instance of Circle, e.g. you can do

Circle & c = *circleIt;

Than you take address of that circle and store it into a pointer

Circle * mCurrentDragCircle  = & (*circleIt);

Hope this helps.

Upvotes: 4

Related Questions