Converting a Pointer to Reference, Costly? [duplicate] - c++

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How expensive is it to dereference a pointer in C++?
If I've got a pointer to an object, let's say Object *ptr;, and I want to pass that to a method of the form void foo(Object& obj) I understand that I need to write:
foo(*ptr);
But why dereference ptr? Wouldn't it make sense to just pass it foo(ptr);? I'm worried *ptr might be making a copy of the original object, or at the least not merely passing to foo the address to work with.
Can anyone clear this up for me? Is passing *ptr a potential bottleneck, for code that expects this to behave just as fast as if the function had been void foo(Object *obj); and called via foo(ptr)?

Whether passing *ptr does make a copy or not depends on whether the called function expects an Object or an Object &.
In the former case, a copy would be made. In the latter case (i.e., your case), no copy would be made.

I'm worried *ptr might be making a copy of the original object.
You're wrong. Dereferencing a pointer doesn't make any copy!
void f(Object & obj); //note it takes the argument by reference
Object *ptr = get();
foo(*ptr);
At the last line of this code there is no copy. The Standard gives you that guarantee.
However, if f takes the argument by value, then there will be copy.
The bottomline: the reference in the function parameter is used to avoid copy (often) or as ouput parameter (occasionally)!

Passing an object by reference just passes the pointer so foo(*ptr) is correct and won't copy the object. Why dereference it? Because the function signature wants an object, not a pointer to an object. C++ is a strongly typed language.

To pass reference to a function, you have to pass the object like you do in value semantics. Pointers are not references since they are entity semantics (addresses).
If you dereference a pointer, you get an actual value, that can be embedded as a reference.

References and Pointers are the same. But References have their own advantage and that is they can not be null ( though they can but it's kinda hard to make a null reference ) so you can omit the check against the nullptr. You can use . instead of -> which is a character shorter xD. About your question since the pointers are references are the same in the end there won't be any gains choosing one over the other. I mean the codes bellow are the same when compiled.
void foo(int &r) {}
and
void foo(int *p) {}
when you use a reference there will be a dereferencing in the background.
Hope it helped.

Related

Using Bit-wise operators with an Enum and an unsigned char - Results in 0 [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
What's the difference between passing by reference vs. passing by value?
I read that in C arguments are passed by value, but what's is the difference between passing arguments by value (like in C) or by refencence (like C++ - C#)?
What's the difference between a pointer and a reference?
void with_ptr(int *i)
{ *i = 0; }
void with_ref(int &i)
{ i = 0; }
In these cases are modified both value? If yes, why C++ allows to pass arguments by reference? I think it is not clear inside the function that the i value could be modified.
what's is the difference between passing arguments by value or by reference
If you pass by value, changes to the variable will be local to the function, since the value is copied when calling the function. Modifications to reference arguments will propagate to the original value.
What's the difference between a pointer and a reference?
The difference is largely syntactic, as you have seen in your code. Furthermore, a pointer can be reassigned to point to something else (unless it’s declared const), while a reference can’t; instead, assigning to a reference is going to assign to the referenced value.
I think it is not clear inside the function that the i value could be modified.
On the contrary, it’s absolutely clear: the function signature tells you so.
There’s actually a case to be made that it’s not clear outside the function. That’s why original versions of C# for instance mandated that you explicitly annotate any by-reference calling with ref (i.e. f(ref x) instead of plain f(x)). This would be similar to calling a function in C++ using f(&x) to make it clear that a pointer is passed.
But in recent versions of C#, the use of ref for calling was made optional since it didn’t confer enough of an advantage after all.
Consider this:
1) Passing by reference provides more simple element access i instead of *i
2) Generally you cannot pass null reference to a method, but can pass a null pointer
3) You can't change the address of reference, but can change it for a pointer(although, as pointer itself passed by value, this change will be discarded upon function exit)
Hope, this helped a bit
Actually, in the first case, you can't modify the argument. The pointer itself is immutable, you can only modify the value it points to.
If yes, why C++ allows to pass arguments by reference?
Because pointers can very easily be miss-used. References should almost always be prefered. For your case, what if you pass a NULL to with_ptr? You'll get undefined behavior, which is not possible if you use with_ref.
I think it is not clear inside the function that the i value could be modified.
It is very clear. If you see a function that takes a parameter by non-const reference, you can assume it will be changed.
I think that a method can only change an argument's value, if this is passed by reference. If you pass a argument by value in a method, then whatever change you make to its value, this will no be available in the parent method.
As far as I know, I think the reference is safer to use in a sense that it can't be modified (always points to the same thing), and should be initialized if it's a local variable. Pointer, however, can be change to point to somewhere else.
int x = 10;
int &y = x;
int *p = &x;
p++; //Legal if you know what's next
y++; // Increases the value of x. Now x = y = 11;
As my two cents, I think reference variables are mere alternative names for the same memory address by which it was initialized. This also explains pretty nice:
http://www.dgp.toronto.edu/~patrick/csc418/wi2004/notes/PointersVsRef.pdf

How to pass the unique pointer to specific param required in function?

A short yet effective example below:
std::unique_ptr<float> x(new float[whatever_size]);
I have a function with prototype:
void function(float*&);
How can I go about calling it by passing in the x.
I tried:
function(x.get()); // complains no argument matches float*&
function(&x.get()); // complains requires lvalue.
A short answer with an explanation would be great.
Thanks!
To start with, you should know that a unique pointer doesn't magically protect you from messing up memory management. Your use case is extremely fishy, and I would caution you to not assume a unique pointer will solve everything and anything.
function expects a modifiable lvalue reference. The call x.get() returns an rvalue. Naturally the reference won't bind to it, no matter how hard you try. Now, the obvious solution is to introduce a temporary:
auto *f = x.get();
function(f);
But that may come back and shoot you in the foot if function needs to actually modify f, the pointer and not the pointee.
Since you mentioned it a comment that it indeed modifies its argument. You must reliniquish ownership from the unique pointer before the call, and give it back after:
auto *f = x.release();
function(f);
x.reset(f);
That is the only way the change will reflect in x. But again, it's still a bit fragile.
The problem here is that the function can modify the pointer you pass to it (passed by non-const reference), potentially re-seating it. If that is the case, then you would have to do something like this:
std::unique_ptr<float[]> x(new float[N]); // remember the array type []
float* fp = x.release();
func(fp);
x.reset(fp);
But the critical point is passing in a proper (named) pointer, not just a temporary pointer returned by x.get().
Your error occurs because the function is unable to modify the temporary pointer returned by the function x.get(). You have to give it a real pointer that can change value.

when does a function have to return a reference in c++ [duplicate]

This question already has answers here:
Is the practice of returning a C++ reference variable evil?
(16 answers)
Closed 9 years ago.
In c++, under what scenarios do we have to return a reference from a function? I understand using references as function inputs, but for function outputs, why cannot we only return values or pointers?
References are used to provide assignment to return values of functions. Sounds odd, but as an example, the array assignment operator in c++ is a function that actually returns a reference to the element at the index parameter so that it can be assigned to, e.g.
class Array {
public:
int& operator[] (const int& index);
...
};
Allowing the following syntax:
Array a;
a[4] = 192;
Inspired by the eternally helpful C++ FAQ:
https://isocpp.org/wiki/faq/references#returning-refs
I'm not sure there are any places where you must return a reference.
Overloading operator++() springs to mind, but it's still not mandated to return a reference. The usual rules apply, though: if you can return a pointer to something, you can safely return a reference in most cases. The key thing is not to return a reference to something that goes out of scope - like a variable that is local to that function. Returning a reference to *this is quite common.
Returning a value is a valuable thing to be able to do, because it either (A) makes a copy of the returned thing, or (B) makes maximum use of move semantics (C++11) and/or the Return Value Optimization (RVO on wikipedia).
If you don't need or want a copy, then returning by reference for value types is usually what you want, since you're unlikely to want pointer-like usage, i.e. having to dereference the returned thing with * or ->.
You can return a reference if the object already exists before the function is called.
then it is not a problem.
This post summmarizes it well.
Is the practice of returning a C++ reference variable, evil?
Just remember that you need to return a reference to an object which will exist after the function is terminated. For example, you can do something like this:
Val(X,10) = 1;
where Val is a function which returns (say) a reference to the 10th element in a list thus setting it to 1.
Returning a reference from a function has the same advantages and disadvantages as returning a pointer.
Returning a non-const reference or pointer allows the caller to write to member variables and call non-const member functions.
However, the object referred to had better have a lifetime longer than the caller requires otherwise the program goes into the realms of undefined behaviour.
On the subject of must return a reference, it is useful for syntactic sugar as with operators, which if returning pointers would require the caller to dereference the pointer.

What's the difference between passing argument by value and by reference? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
What's the difference between passing by reference vs. passing by value?
I read that in C arguments are passed by value, but what's is the difference between passing arguments by value (like in C) or by refencence (like C++ - C#)?
What's the difference between a pointer and a reference?
void with_ptr(int *i)
{ *i = 0; }
void with_ref(int &i)
{ i = 0; }
In these cases are modified both value? If yes, why C++ allows to pass arguments by reference? I think it is not clear inside the function that the i value could be modified.
what's is the difference between passing arguments by value or by reference
If you pass by value, changes to the variable will be local to the function, since the value is copied when calling the function. Modifications to reference arguments will propagate to the original value.
What's the difference between a pointer and a reference?
The difference is largely syntactic, as you have seen in your code. Furthermore, a pointer can be reassigned to point to something else (unless it’s declared const), while a reference can’t; instead, assigning to a reference is going to assign to the referenced value.
I think it is not clear inside the function that the i value could be modified.
On the contrary, it’s absolutely clear: the function signature tells you so.
There’s actually a case to be made that it’s not clear outside the function. That’s why original versions of C# for instance mandated that you explicitly annotate any by-reference calling with ref (i.e. f(ref x) instead of plain f(x)). This would be similar to calling a function in C++ using f(&x) to make it clear that a pointer is passed.
But in recent versions of C#, the use of ref for calling was made optional since it didn’t confer enough of an advantage after all.
Consider this:
1) Passing by reference provides more simple element access i instead of *i
2) Generally you cannot pass null reference to a method, but can pass a null pointer
3) You can't change the address of reference, but can change it for a pointer(although, as pointer itself passed by value, this change will be discarded upon function exit)
Hope, this helped a bit
Actually, in the first case, you can't modify the argument. The pointer itself is immutable, you can only modify the value it points to.
If yes, why C++ allows to pass arguments by reference?
Because pointers can very easily be miss-used. References should almost always be prefered. For your case, what if you pass a NULL to with_ptr? You'll get undefined behavior, which is not possible if you use with_ref.
I think it is not clear inside the function that the i value could be modified.
It is very clear. If you see a function that takes a parameter by non-const reference, you can assume it will be changed.
I think that a method can only change an argument's value, if this is passed by reference. If you pass a argument by value in a method, then whatever change you make to its value, this will no be available in the parent method.
As far as I know, I think the reference is safer to use in a sense that it can't be modified (always points to the same thing), and should be initialized if it's a local variable. Pointer, however, can be change to point to somewhere else.
int x = 10;
int &y = x;
int *p = &x;
p++; //Legal if you know what's next
y++; // Increases the value of x. Now x = y = 11;
As my two cents, I think reference variables are mere alternative names for the same memory address by which it was initialized. This also explains pretty nice:
http://www.dgp.toronto.edu/~patrick/csc418/wi2004/notes/PointersVsRef.pdf

what's the difference between object * x and object& x in c++ [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Difference between pointer variable and reference variable in C++
suppose I'm trying to pass a reference to object x to a c++ function...
what's the difference between
pass(Object * x){
}
and
pass(Object& x){
}
and how would you access the actual object itself when the pointer/reference is declared using the different methods...
for instance if I have Object * x, how would I actually access the actual object that is referenced by x
same with Object& x
The first is a pass by pointer. The second is a pass by reference.
As for usage, a pointer must be "dereferenced" before it can be used. That is done with the * and -> operators:
void do_something(Object * x)
{
Object & ref = *x; // * returns a reference
ref.method();
x->method(); // same as (*x).method()
}
References have no such restriction:
void do_something(Object & x)
{
x.method();
}
However, references can only point to a single object for their whole lifetime, while pointers can change target and (as John mentionned below) point to "nothing" (that is, NULL, 0 or, in C++0x, nullptr). There is no such thing as a NULL reference in C++.
Since references are easier to use and less error-prone, prefer them unless you know what you're doing (pointers are a pretty tough subject).
Pass by reference means the caller should guarantee that the referred object is valid. Pass by pointer usually requires the function to check whether the pointer is NULL.
Pass by reference also means the function don't care about the lifecycle of the object. Pass by pointer may require the function to destruct the object.
So, apparently, pass by reference has clear semantics, less possibility, less error-prone.