Archived

This topic is now archived and is closed to further replies.

Feldi

pointer, reference, what?

Recommended Posts

these two things it seems to do the same but why would be the 1st method be preffered over the 2nd one, (if it would) void Point::Set(const Point &p) { x=p.x; y=p.y; } void Point::Set(Point *p) { x=p->x; y=p->y; }

Share this post


Link to post
Share on other sites
In the second case p (pointer) could be NULL, causing an access violation, whereas in the first case p (reference) will always be valid (unless you do some ugly pointer dereferencing).

Use references when you always expect a valid parameter, use pointers, when you need some "invalid" parameter value.

Share this post


Link to post
Share on other sites
Internally references are pointers so the two examples generate identical assembly/hexcode output. It's just the C++ that's different, and as Endurion said, references are always assigned to something valid. And in case you were wondering, the reason you pass "Point &p" instead of "Point p" is because everything passed to functions needs to be pushed on and off the stack, which isn't very fast, so you want to reduce the memory to push/pop. A reference/pointer is 4 bytes (32 bits) but the actual value being passed if you don't use a reference/pointer can be much larger... Point is probably 8 bytes, so it's a slight savings.

If you're passing something 4 bytes or [especially] less, and it's only used for input, you do not want to pass it by reference/pointer.

~CGameProgrammer( );

-- Post screenshots of your projects. 100+ posts already in the archives.

[edited by - CGameProgrammer on October 21, 2003 6:22:43 AM]

Share this post


Link to post
Share on other sites
GameProgrammer and Endurion, thanks for your answers. Very helpfull!
Abdulla, I knew how and why to use pointers, but I just
had no deeper understanding why would one use referencing
instead of pointers, but now I do.

Share this post


Link to post
Share on other sites
quote:
Original post by sbennett
One other thing: copy constructors and assignment operators have to take references as arguments, IIRC.


No, you could just as easily make a copy constructor using a pointer... example


struct SomeStruct
{
int x;
operator =(const SomeStruct *p)
{
x = p->x;
//Could also do: x = *p.x;

}
operator =(const SomeStruct &p)
{
x = p.x;
}
};

SomeStruct S1, S2;

S1.x = 10;
S2 = &S1; //Assign with the pointer version

S2 = S1; //Assign using a reference



This is done just the same as it is when calling functions with pointers, you must take it''s address first.

Share this post


Link to post
Share on other sites
quote:
No, you could just as easily make a copy constructor using a pointer...

No, that would be a constructor (even if it makes a copy), not a copy constructor:

struct A
{
A(const A*)
{
}
};
..
A a;
A b(a);

b(a) would still call a compiler generated copy ctor: A(const A&). The same goes for the default assignment operator: A& operator=(const A&).

Share this post


Link to post
Share on other sites
If I understood correctly, necromancer_df isn''t quite correct. In the case of a pointer being passed to a function, you can not change the address that the pointer points to (i.e. make it point to a different object.) You can only change the attributes of the object being pointed at or, by way of pointer math, change some other location in memory. This is because you only receive a copy of the pointer. If you change the address in the pointer your only changing your copy and not the original. If you want or need to change the pointer, you can pass the pointer by reference or pass the pointer by pointer. In which case you cannot change the pointers pointer to point to a different pointer... (add recursion).

Here''s some code to make my point.

void f(int *p)
{
p = new int;
// does not change the pointer that was passed in
// and will cause a memory leak
}

This is how I understand it to work... if I''m wrong feel free to flame.

-Shags


Share this post


Link to post
Share on other sites
quote:
Original post by Shags
If I understood correctly, necromancer_df isn''t quite correct. In the case of a pointer being passed to a function, you can not change the address that the pointer points to (i.e. make it point to a different object.) You can only change the attributes of the object being pointed at or, by way of pointer math, change some other location in memory. This is because you only receive a copy of the pointer. If you change the address in the pointer your only changing your copy and not the original. If you want or need to change the pointer, you can pass the pointer by reference or pass the pointer by pointer. In which case you cannot change the pointers pointer to point to a different pointer... (add recursion).

Here''s some code to make my point.

void f(int *p)
{
p = new int;
// does not change the pointer that was passed in
// and will cause a memory leak
}

This is how I understand it to work... if I''m wrong feel free to flame.

-Shags




No, you''re confusing references with pointers. A pointer can be reassigned, like setting a NULL pointer to "new int". You cannot do that with a reference. For example:

int i=3;
int j=5;
int &m = i;
m = j; // this sets i = j; it doesn''t reassign m


m = &j; // syntax error, conversion from int* to int


m = (int)&j; // this sets i to the address of j



~CGameProgrammer( );

-- Post screenshots of your projects. 100+ posts already in the archives.

Share this post


Link to post
Share on other sites
CGameProgrammer, I totally agree with you. You CAN assign a pointer to something else or even NULL, but in the case were a pointer is passed to a function, changing it will NOT effect the pointer outside the function because you only got a copy of it.

Share this post


Link to post
Share on other sites
quote:
Original post by Feldi
these two things it seems to do the same
but why would be the 1st method be preffered over the
2nd one, (if it would)

void Point::Set(const Point &p)
{
x=p.x;
y=p.y;
}


It requires no & at the call site. It doesn''t allow the method to modify p. It can be implemented as copy in, copy out to remove aliasing. It removes the need for checks against null.

Share this post


Link to post
Share on other sites
quote:
Original post by Shags
CGameProgrammer, I totally agree with you. You CAN assign a pointer to something else or even NULL, but in the case were a pointer is passed to a function, changing it will NOT effect the pointer outside the function because you only got a copy of it.

Wellll... you''re not really doing a fair comparison. This is fairer:

void Function ( int &i )
{
i = 3;
}

versus this:

void Function ( int *i )
{
*i = 3;
}

Both those work, it''s just that with the pointer, you have to dereference it. References make things simpler because the rereferencing is implied. With a pointer, you cannot say:

void Function ( int *i )
{
i = 3;
}

This is an error. You can set pointers to 0 but not to any other value, *directly*.

~CGameProgrammer( );

-- Post screenshots of your projects. 100+ posts already in the archives.

Share this post


Link to post
Share on other sites
Or try:

void Function ( const int &i )
{
use i
}

versus:

void Function ( const int * const i )
{
use *i
}

In which case neither can be reassigned and neither can have the ints they point to changed. This is probably pretty close to how it works under the hood.

Image loads when I''m online!The following statement is true. The previous statement is false.
Shameless promotion:
FreePop: The GPL Populous II clone.

Share this post


Link to post
Share on other sites