Two ways of passing by reference in C++? [duplicate] - c++

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
What are the differences between pointer variable and reference variable in C++?
How to pass objects to functions in C++?
I am learning about reference parameters and got the following question:
What is the difference between this:
void B(int* worthRef) {
*worthRef += 1;
}
int main() {
int netWorth = 55;
B(&netWorth);
return 0;
}
And this:
void B(int &worthRef) {
worthRef += 1;
}
int main() {
int netWorth = 55;
B(netWorth);
return 0;
}

The first one (int *) passes a pointer-to-integer by value; the second (int &) passes an integer by reference. Both methods can be used to implement abstract "reference semantics", but in C++ you should use actual references when possible.
When you use pointers to implement reference semantics, you pass by value a pointer to the object that you want to refer to, and you dereference the pointer to obtain the actual object reference. In C, where you have no references in the language, that's the only way to implement reference semantics, but in C++ you have actual reference types in the language for this purpose.
Note that passing a pointer can be used a little differently from a reference, since you can pass a null pointer to convey additional semantics, and you can also modify the pointer variable (e.g. for using the local copy of the pointer in the callee scope to traverse an array).
But in a nutshell: Use references. Don't use naked pointers in C++. (To implement reference semantics, you use references, and to implement whatever else naked pointers can be (ab)used for, use the appropriate higher-level idiom.) The fundamental problem with naked pointers is that they convey no ownership semantics, and C++ has many far better tools to write maintainable, local and self-documenting code.

Here you are passing the address of the int:
void B(int* worthRef) {
*worthRef += 1;
}
The parameter is a pointer. The address passed may be 0 (or NULL). Also used in C. The pointer may altered within B: ++worthRef - why you would prefer that...
Here, the implementation takes the address of the parameter:
void B(int &worthRef) {
worthRef += 1;
}
The parameter is a C++ reference. The address passed must not be 0, and may not be altered (of course, what it refers to may be altered if not const, as seen in your example). This is the default written style in most C++ circles. Mechanically, a reference is a bit of syntactic sugar, but it is absolutely useful to convey intent and offer guarantees.
Stylistically, some people prefer the former for parameters which may mutate. I use the latter wherever possible (and legal) -- it's more conventional for C++.

Related

Meaning of pass by reference in C and C++?

I am confused about the meaning of "pass by reference" in C and C++.
In C, there are no references. So I guess pass by reference means passing a pointer. But then why not call it pass by pointer?
In C++, we have both pointers and references (and stuff like iterators that lies close). So what does pass by reference mean here?
In colloquial usage, "pass by reference" means that, if the callee modifies its arguments, it affects the caller, because the argument as seen by the callee refers to the value as seen by the caller.
The phrase is used independent of the actual programming language, and how it calls things (pointers, references, whatever).
In C++, call-by-reference can be done with references or pointers. In C, call-by-reference can only be achieved by passing a pointer.
"Call by value":
void foo( int x )
{
// x is a *copy* of whatever argument foo() was called with
x = 42;
}
int main()
{
int a = 0;
foo( a );
// at this point, a == 0
}
"Call by reference", C style:
void foo( int * x )
{
// x is still a *copy* of foo()'s argument, but that copy *refers* to
// the value as seen by the caller
*x = 42;
}
int main()
{
int a = 0;
foo( &a );
// at this point, a == 42
}
So, strictly speaking, there is no pass-by-reference in C. You either pass the variable by-value, or you pass a pointer to that variable by-value.
In C, there are no references
There are no reference variables. But you can refer to objects using pointers. Therefore pointers are "references" from an abstract point of view.
But then why not call it pass by pointer?
You can call it pass by pointer. Reference is a more general term than pointer. It is often preferable to use the more general term when you want to discuss abstractions and want to ignore implementation details. You would call it pass by reference for the same reason that you call a variable "integer" rather than "int32_t".
In C++, we have both pointers and references (and stuff like iterators that lies close). So what does pass by reference mean here?
Depends on context. Often it means that the function argument is a reference variable, but it may also refer to a pointer, iterator, a reference wrapper... anything that referes to an object.
Reference is an abstract concept that exists beyond c and c++; even beyond programming. In c++, the term is ambiguous with reference variables and the context and convention (which isn't universal) determines the meaning.
In C, there are no any reference variables, but you can pass by reference with using pointers.
In wikipedia, there is this definition.
In call-by-reference evaluation (also referred to as pass-by-reference), a function receives an implicit reference to a variable used as argument, rather than a copy of its value. So this term is for type of parameter passing as mentioned by Thomas. So yes, since C is older than C++, also this idea is older than C++.
However, in C++ both pointers and references can be used for passing to the function(Call by address and call by reference). Actually they are working the same way, they have only a few differences.
Once a reference is created, it cannot be later made to reference
another object; it cannot be reseated. This is often done with
pointers.
References cannot be NULL. Pointers are often made NULL to indicate
that they are not pointing to any valid thing.
A reference must be initialized when declared. There is no such
restriction with pointers
With these differences, if you use call by reference instead of call by pointer, you can reduce the possibility of NULL pointer error kind of problems.
Let's clear your confusion.
In C, there are no references. So I guess pass by reference means passing a pointer. But then why not call it pass by pointer?
Because every argument passing in C is pass-by-value. Even a pointer argument is a copy. But it contains (or points to, if you prefer) the same value -- memory address. That is how you can change the variable it points to, but not the pointer itself. Since it's a copy, whatever you do will not affect the pointer on the caller level.
In C++, we have both pointers and references (and stuff like iterators that lies close). So what does pass by reference mean here?
It means, that the argument is an alias of a variable on the caller level, not a copy, which allows us to change it.
Hope that helped.
A reference in general is an instance that is referencing something else. Thus in a wider sense, also a pointer can be considered as one possible implementation of a reference. References in C++ are just called references, because apart from referencing something they offer no other features.
Pass-by-reference is used in general to distinguish from pass-by-value. Whether it is via pointer or via a reference is often just a minor detail. However, with C++ references it is imho more clear what is the purpose of the function parameter. Eg:
int foo(int& a); // pass-by-reference
int foo(const int& a); // is pratically pass-by-value
// (+ avoiding the copy of the parameter)
on the other hand, with references (as compared to pointers) it is not so obvious at the call site if it is pass-by-value or pass-by-reference. E.g.
int x;
int y = foo(x); // could be pass-by-value or pass-by-reference
int z = foo(&x); // obviously pass-by-reference (as a pointer)
Imagine you have to paint your house...
by value: you bring a copy of your house to the painter => much effort (maybe on rails)
by reference: you give your house address to the painter so he can come and paint it
"Pass by reference" (or "call by reference") is a term for a type of parameter passing when calling a function, and the idea is older than C++. It does not necessarily have to be done using C++ "references". C doesn't have a built-in mechanism to do this, so you have to use pointers.
Just to add to the answers, referencing does not mean reference by address. The compiler may use any method to reference to a variable.
when you pass something by reference you're working with the address and not the value of a variable directly, If you use a reference parameter you're getting the address of the variable you pass in.
From there you can manipulate it how ever you want as the variable you passed in WILL change if you change the reference in the function. It's an easier way to work with large amounts of a data it really just saves on memory etc..
In C there are two concepts
1. Call by value - Here copy of values are passed so actual values will not change outside the function.
2. Call by reference - but here actual values (Address of actual operands) are passed so it will change the values globally.
Where in C++ there are two concepts
1. Pass by value - it is same as c, actual values will not change, scope of this values are of function only.
2. Pass by Reference - actual values (Address of actual operands) are passed so it will change the values globally, it means if values gets changed then it will affect in whole program.
In Pass by Reference, the address of operands are passed that's why it is called as Pass By Reference not as pointer.

Pointer arguments for functions [duplicate]

This question already has answers here:
What is a reference variable in C++?
(12 answers)
Closed 9 years ago.
One thing that I have not been able to understand is when to use certain types of pointers for arguments in functions.
Consider a function that receives an integer as its parameter, and doubles whatever that value may be. A function for that could be:
void doubleTheValue(int *myNum)
{
*myNum *= 2;
}
int main()
{
int number = 2;
doubleTheValue(&number);
// prints 4
cout << number << endl;
return 0;
}
This makes sense to me. The function receives an integer pointer, and you pass in a reference to the variable 'number' and it changes the value. Now, what confuses me is if you did this instead:
void doubleTheValue(int &myNum)
{
myNum *= 2;
}
int main()
{
int number = 2;
doubleTheValue(number);
// this also prints 4
cout << number << endl;
return 0;
}
Note the argument for the function is different. What exactly is this doing internally, and why would you use it over the aforementioned method?
What exactly is this doing internally, and why would you use it over the aforementioned method?
In your first example:
void doubleTheValue(int *myNum)
{
*myNum *= 2;
}
you are passing a pointer to the function. A pointer has an implementation defined size. For example, in 64bit architectures the size of a pointer might be 8 byte. In this case (and in general, for primitive types) it's counter productive to pass pointers instead of references (see next paragraph).
In your second example:
void doubleTheValue(int &myNum)
{
myNum *= 2;
}
you are passing a reference to the function. The main difference is that a reference is not even required to take any memory at all. myNum and the original variable could just share the same object in memory.
For other differences between references and pointers I suggest you to take a look at this question. But a general rule of thumb it to always use references when you can. You'll find the need of using pointers in specific situations (like, for example, when you want to accept a null-value).
What exactly is this doing internally, and why would you use it over the aforementioned method?
The & reference is to be read as an equivalence for the pointer reference parameter, but
... with guaranteed initialization
... without need to use a pointer dereference operator * to access the value/members inside the function implementation
To indicate error conditions for the passed parameter you'll need to use a return value type (not void), or throw an exception from inside your function. This generally applies to both variants.
You should understand the difference between a pointer and reference. In many cases we cannot do something using references which we can do using pointers. Although references do not need any memory and they are just tags to a memory location but in comparison with pointer, pointers are far more powerful than references.
The major differences are:
1- A pointer can be re-assigned any number of times while a reference can not be reassigned after initialization.
2-A pointer can point to NULL while reference can never point to NULL.
3-You can't take the address of a reference like you can with pointers
4-There's no "reference arithmetic" (but you can take the address of an object pointed by a reference and do pointer arithmetic on it as in &obj + 5)
From OP, in comments of original post:
Neither of this really give any use for applications nor explain why you would use one over the other which is what I am curious about.
My impression is that people mostly use references because they make the code look cleaner, so that there aren't a lot of * and & floating around.

Pass by pointer & Pass by reference [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
What are the differences between pointer variable and reference variable in C++?
Are there benefits of passing by pointer over passing by reference in C++?
In both cases, I achieved the result.
So when is one preferred over the other? What are the reasons we use one over the other?
#include <iostream>
using namespace std;
void swap(int* x, int* y)
{
int z = *x;
*x=*y;
*y=z;
}
void swap(int& x, int& y)
{
int z = x;
x=y;
y=z;
}
int main()
{
int a = 45;
int b = 35;
cout<<"Before Swap\n";
cout<<"a="<<a<<" b="<<b<<"\n";
swap(&a,&b);
cout<<"After Swap with pass by pointer\n";
cout<<"a="<<a<<" b="<<b<<"\n";
swap(a,b);
cout<<"After Swap with pass by reference\n";
cout<<"a="<<a<<" b="<<b<<"\n";
}
Output
Before Swap
a=45 b=35
After Swap with pass by pointer
a=35 b=45
After Swap with pass by reference
a=45 b=35
A reference is semantically the following:
T& <=> *(T * const)
const T& <=> *(T const * const)
T&& <=> [no C equivalent] (C++11)
As with other answers, the following from the C++ FAQ is the one-line answer: references when possible, pointers when needed.
An advantage over pointers is that you need explicit casting in order to pass NULL.
It's still possible, though.
Of the compilers I've tested, none emit a warning for the following:
int* p() {
return 0;
}
void x(int& y) {
y = 1;
}
int main() {
x(*p());
}
In fact, most compilers emit the same code for both functions calls, because references are generally implemented using pointers.
Following this logic, when an argument of (non-const) reference type is used in the function body, the generated code will just silently operate on the address of the argument and it will dereference it. In addition, when a call to such a function is encountered, the compiler will generate code that passes the address of the arguments instead of copying their value.
Basically, references and pointers are not very different from an implementation point of view, the main (and very important) difference is in the philosophy: a reference is the object itself, just with a different name.
References have a couple more advantages compared to pointers (e. g. they can't be NULL, so they are safer to use). Consequently, if you can use C++, then passing by reference is generally considered more elegant and it should be preferred. However, in C, there's no passing by reference, so if you want to write C code (or, horribile dictu, code that compiles with both a C and a C++ compiler, albeit that's not a good idea), you'll have to restrict yourself to using pointers.
Pass by pointer is the only way you could pass "by reference" in C, so you still see it used quite a bit.
The NULL pointer is a handy convention for saying a parameter is unused or not valid, so use a pointer in that case.
References can't be updated once they're set, so use a pointer if you ever need to reassign it.
Prefer a reference in every case where there isn't a good reason not to. Make it const if you can.
Here is a good article on the matter - "Use references when you can, and pointers when you have to."
Use references all the time and pointers only when you have to refer to NULL which reference cannot refer.
See this FAQ :
http://www.parashift.com/c++-faq-lite/references.html#faq-8.6

Why do parameters passed by reference in C++ not require a dereference operator?

I'm new to the C++ community, and just have a quick question about how C++ passes variables by reference to functions.
When you want to pass a variable by reference in C++, you add an & to whatever argument you want to pass by reference. How come when you assign a value to a variable that is being passed by reference why do you say variable = value; instead of saying *variable = value?
void add_five_to_variable(int &value) {
// If passing by reference uses pointers,
// then why wouldn't you say *value += 5?
// Or does C++ do some behind the scene stuff here?
value += 5;
}
int main() {
int i = 1;
add_five_to_variable(i);
cout << i << endl; // i = 6
return 0;
}
If C++ is using pointers to do this with behind the scenes magic, why aren't dereferences needed like with pointers? Any insight would be much appreciated.
When you write,
int *p = ...;
*p = 3;
That is syntax for assigning 3 to the object referred to by the pointer p. When you write,
int &r = ...;
r = 3;
That is syntax for assigning 3 to the object referred to by the reference r. The syntax and the implementation are different. References are implemented using pointers (except when they're optimized out), but the syntax is different.
So you could say that the dereferencing happens automatically, when needed.
C++ uses pointers behind the scenes but hides all that complication from you. Passing by reference also enables you to avoid all the problems asssoicated with invalid pointers.
When you pass an object to a function by reference, you manipulate the object directly in the function, without referring to its address like with pointers. Thus, when manipulating this variable, you don't want to dereference it with the *variable syntax. This is good practice to pass objects by reference because:
A reference can't be redefined to point to another object
It can't be null. you have to pass a valid object of that type to the function
How the compiler achieves the "pass by reference" is not really relevant in your case.
The article in Wikipedia is a good ressource.
There are two questions in one, it seems:
one question is about syntax: the difference between pointer and reference
the other is about mechanics and implementation: the in-memory representation of a reference
Let's address the two separately.
Syntax of references and pointers
A pointer is, conceptually, a "sign" (as road sign) toward an object. It allows 2 kind of actions:
actions on the pointee (or object pointed to)
actions on the pointer itself
The operator* and operator-> allow you to access the pointee, to differenciate it from your accesses to the pointer itself.
A reference is not a "sign", it's an alias. For the duration of its life, come hell or high water, it will point to the same object, nothing you can do about it. Therefore, since you cannot access the reference itself, there is no point it bothering you with weird syntax * or ->. Ironically, not using weird syntax is called syntactic sugar.
Mechanics of a reference
The C++ Standard is silent on the implementation of references, it merely hints that if the compiler can it is allowed to remove them. For example, in the following case:
int main() {
int a = 0;
int& b = a;
b = 1;
return b;
}
A good compiler will realize that b is just a proxy for a, no room for doubts, and thus simply directly access a and optimize b out.
As you guessed, a likely representation of a reference is (under the hood) a pointer, but do not let it bother you, it does not affect the syntax or semantics. It does mean however that a number of woes of pointers (like access to objects that have been deleted for example) also affect references.
The explicit dereference is not required by design - that's for convenience. When you use . on a reference the compiler emits code necessary to access the real object - this will often include dereferencing a pointer, but that's done without requiring an explicit dereference in your code.

When is the right time to use *, & or const in C++?

I was studying pointers references and came across different ways to feed in parameters. Can someone explain what each one actually means?
I think the first one is simple, it's that x is a copy of the parameter fed in so another variable is created on the stack.
As for the others I'm clueless.
void doSomething1(int x){
//code
}
void doSomething2(int *x){
//code
}
void doSomething3(int &x){
//code
}
void doSomething3(int const &x){
//code
}
I also see stuff like this when variables are declared. I don't understand the differences between them. I know that the first one will put 100 into the variable y on the stack. It won't create a new address or anything.
//example 1
int y = 100;
//example 2
int *y = 100;
//Example 3: epic confusion!
int *y = &z;
Question 1: How do I use these methods? When is it most appropriate?
Question 2: When do I declare variables in that way?
Examples would be great.
P.S. this is one the main reasons I didn't learn C++ as Java just has garbage collection. But now I have to get into C++.
//example 1
int y = 100;
//example 2
int *y = 100;
//Example 3: epic confusion!
int *y = &z;
I think the problem for most students is that in C++ both & and * have different meanings, depending on the context in which they are used.
If either of them appears after a type within an object declaration (T* or T&), they are type modifiers and change the type from plain T to a reference to a T (T&) or a pointer to a T (T*).
If they appear in front of an object (&obj or *obj), they are unary prefix operators invoked on the object. The prefix & returns the address of the object it is invoked for, * dereferences a pointer, iterator etc., yielding the value it references.
It doesn't help against confusion that the type modifiers apply to the object being declared, not the type. That is, T* a, b; defines a T* named a and a plain T named b, which is why many people prefer to write T *a, b; instead (note the placement of the type-modifying * adjacent the object being defined, instead of the type modified).
Also unhelpful is that the term "reference" is overloaded. For one thing it means a syntactic construct, as in T&. But there's also the broader meaning of a "reference" being something that refers to something else. In this sense, both a pointer T* and a reference (other meaning T&) are references, in that they reference some object. That comes into play when someone says that "a pointer references some object" or that a pointer is "dereferenced".
So in your specific cases, #1 defines a plain int, #2 defines a pointer to an int and initializes it with the address 100 (whatever lives there is probably best left untouched ), and #3 defines another pointer and initializes it with the address of an object z (necessarily an int, too).
A for how to pass objects to functions in C++, here is an old answer from me to that.
From Scott Myers - More Effective C++ -> 1
First, recognize that there is no such thing as a null reference. A reference must always refer to some object.Because a reference must refer to an object, C++ requires that references be initialized.
Pointers are subject to no such restriction. The fact that there is no such thing as a null reference implies that it can be more efficient to use references than to use pointers. That's because there's no need to test the validity of a reference before using it.
Another important difference between pointers and references is that pointers may be reassigned to refer to different objects. A reference, however, always refers to the object with which it is initialized
In general, you should use a pointer whenever you need to take into account the possibility that there's nothing to refer to (in which case you can set the pointer to null) or whenever you need to be able to refer to different things at different times (in which case you can change where the pointer points). You should use a reference whenever you know there will always be an object to refer to and you also know that once you're referring to that object, you'll never want to refer to anything else.
References, then, are the feature of choice when you know you have something to refer to, when you'll never want to refer to anything else, and when implementing operators whose syntactic requirements make the use of pointers undesirable. In all other cases, stick with pointers.
Read S.Lippmann's C++ Premier or any other good C++ book.
As for passing the parameters, generally when copying is cheap we pass by value. For mandatory out parameters we use references, for optional out parameters - pointers, for input parameters where copying is costly, we pass by const references
Thats really complicated topic. Please read here: http://www.goingware.com/tips/parameters/.
Also Scott Meiers "Effective C++" is a top book on such things.
void doSomething1(int x){
//code
}
This one pass the variable by value, whatever happens inside the function, the original variable doesn't change
void doSomething2(int *x){
//code
}
Here you pass a variable of type pointer to integer. So when accessing the number you should use *x for the value or x for the address
void doSomething3(int &x){
//code
}
Here is like the first one, but whatever happens inside the function, the original variable will be changed as well
int y = 100;
normal integer
//example 2
int *y = 100;
pointer to address 100
//Example 3: epic confusion!
int *y = &z;
pointer to the address of z
void doSomething1(int x){
//code
}
void doSomething2(int *x){
//code
}
void doSomething3(int &x){
//code
}
And i am really getting confused between them?
The first is using pass-by-value and the argument to the function will retain its original value after the call.
The later two are using pass-by-reference. Essentially they are two ways of achieving the same thing. The argument is not guarenteed to retain its original value after the call.
Most programmers prefer to pass large objects by const reference to improve the performance of their code and provide a constraint that the value will not change. This ensures the copy constructor is not called.
Your confusion might be due to the '&' operator having two meanings. The one you seem to be familiar with is the 'reference operator'. It is also used as the 'address operator'. In the example you give you are taking the address of z.
A good book to check out that covers all of this in detail is 'Accelerated C++' by Andrew Koening.
The best time to use those methods is when it's more efficient to pass around references as opposed to entire objects. Sometimes, some data structure operations are also faster using references (inserting into a linked list for example). The best way to understand pointers is to read about them and then write programs to use them (and compare them to their pass-by-value counterparts).
And for the record, knowledge of pointers makes you considerably more valuable in the workplace. (all too often, C++ programmers are the "mystics" of the office, with knowledge of how those magical boxes under the desks process code /semi-sarcasm)