Difference between the * and & operator in function calls [duplicate] - c++

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
C++ functions: ampersand vs asterisk
What are the distinctions between the various symbols (*,&, etc) combined with parameters?
I am wondering the difference between the address operator & and the deference operator * in a C++ function call. For example take the following function
void foo (std::string& param)
{
param = "Bar.";
std::cout << param.size();
}
and let's call it in our main() function like so...
int main()
{
std::string test;
foo(test); //Why not foo(&test)?
std::cout << test; //Prints out the value "Bar."
}
First off, why does the & operator allow me to assign a value as if it were a pointer (assigning it a value that survives the RAII and scope of the function foo() when it's not a pointer) as it is able to be printed out in my main() function even though it's not static? I am assuming it is not a pointer because I am able to access the size() method by using the . operator instead of the -> which is used for pointers.
Secondly, what would be the difference between using the & operator in a function parameter vs. using the * operator? Is it even different than just a plain variable like std::string param? It appears to be called like that (foo(test) instead of foo(&test)).

& function parameter specifically signifies that this parameter is being passed-in by reference (traditionally compilers implement this as a pointer) which is why you see the effect of this assignment in your main().
static would have nothing to do with that.
The difference in declaring a parameter to a function using & and * is that the second one allows a nullptr (or a non-existent or just a plain invalid address) to be passed-in while the & guarantees that there's a real object being referenced by this function's argument. Other than that both provide similar functionality of allowing an original object to be changed via it's reference.

test on it's own (without &) would pass a copy to the string to the function, whilst the & means it will pass a reference.
FYI: When you don't need a reference, best-practise dictates passing all objects as const references.

Related

C++ demo function uses both a const argument that is a pointer why is this?

In the std::filesystem c++17 library documentation there are multiple instances of an input to a function being a const and yet also using its reference.
void demo_exists(const fs::path& p, fs::file_status s = fs::file_status{});
Surely the const and the & contradict. My understanding is that const is used when you don't want the variable to be modified and an & when you want to mutate multiple arguments within the function without having to return them as an array after.
Surely using both const and & is oxymoronic and confusing or is there a reason why they are both used?
Thanks in advance
original example from the docs https://en.cppreference.com/w/cpp/filesystem/exists
My understanding is that const is used when you don't want the variable to be modified and an & when you want to mutate multiple arguments within the function without having to return them as an array after.
That is not quite correct. You pass by reference when you want to avoid a copy. Though since move-semantics have been introduced, many uses of passing by (const) reference are obsolote.
You declare the reference as const when the method does not modify the parameter and only non-const when it has to modify it.
Example:
void foo(const SomeLargeObject&); // pass by reference to avoid copy
void bar(int&); // pass non-const reference to modify the parameter
PS:
C++ demo function uses both a const argument that is a pointer why is this?
There is not a single pointer here. What might be confusing is that the address-off operator and the symbol for reference types are the same: &. However, it has two very different meanings:
int x = 0;
int* pointer_to_x = &x; // here it is address-of operator
int& reference_to_x = x; // here it declares reference_to_x as reference to int
PS2: For the sake of completeness I want to mention one more thing. The second unfortunate thingy in C++ here is that "references" usually refer to C++ references (see examples above). On the other hand the term "pass by reference" is used in a wider context and uses "reference" in the meaning of "some reference", ie it can be a reference or it can be a pointer. In the wider sense (*) those two are both pass-by-reference allowing the method to modify what is refered to:
void foo(int& x); // A
void foo(int* x); // B
In C++ references (A) should be prefered unless "no value" (ie a null-pointer) is a valid input.
(*) To be precise the pointer itself is actually passed by value.

What is the use of "const" functions? [duplicate]

This question already has answers here:
what does const mean in c++ in different places
(4 answers)
Functions returning a const value [duplicate]
(1 answer)
Closed 9 years ago.
This code looks weird:
const double square(double x) {
return x*x;
}
Common sense tells me that const in this context means either
the function returns a const double
OR
it promises not to change the double that was passed in. But it was passed in by value! I don't understand
OR
I know that const member functions promise not to change *this, but this is not even a member function.
Edit
What's the point to return a const double if you can save the result in a non-const variable and edit it??
double var = square(4.5); // no compile error
var = 0.3;
It is weird. As you say:
the function returns a const double
For a user-defined type, this would prevent you from modifying the return value:
square(2) += 5; // Error
although, as noted in the comments, this isn't allowed for a built-in type like double anyway. Even for user-defined types, while you probably don't want to write code like that, there's no point preventing it either.
For more complicated types, returning a const value can actually be harmful: it inhibits move semantics, since a const object can't be moved from. This could hurt performance.
That is not a "const function". It is a function which returns a value that is const. A "const function" only applies to member functions, and then the const goes on the right, after the parameter list.
The utility of this for a simple value type is dubious. However, if you were returning a reference to const or a const pointer, or something else, then it could have merit.
The only thing that returning a const of a simple type by value does is make sure that it can't be captured by non-const r-value reference in C++11. Otherwise, they'll just copy the value and be on their way.
In the example you give, and for any POD type, it makes little sense, but for more complex types it can make sense:-
const SomeClass &SomeFunction ();
which returns a reference to a const object.
A const function with const before the return value is usually used where the function returns a pointer (or perhaps a reference) to say that it will only return const pointers. This one returns a double and that means it only returns doubles that are const.
It returns a const double type variable.
If you do it like this, most compilers give a warning if you try to assign the returned value to a double type.

Pointers vs. References in C++ function arguments [duplicate]

This question already has answers here:
What are the differences between a pointer variable and a reference variable?
(44 answers)
Closed 9 years ago.
I was wondering how to make a function alter two variables (the return and another one) and I stumbled upon calling the function with an '&' before the parameter (which I understand to mean the address of the parameter) then throughout your function, referencing it with the '*' sign (which I guess is a "dereference" and means it alters the object at the address).
Anyways, this was all going fine, then a friend said you can just call the function with the variable directly, refer to the variable with an & before it in the header, and treat it normally throughout the function. This seems way easier, so why isn't there more about it on the web? Is one style more correct than the other?
void foo(int &junk) //The way the friend said
{
junk++;
}
void oof(int *junk) //what I found, and what the internet seems full of
{
(*junk)++;
}
int main ()
{
int junk=1;
std::cout << junk << "\n";
foo(junk);
std::cout << junk << "\n";
oof(&junk);
std::cout << junk;
}
This outputs:
1
2
3
So everything works fine, I'd assume.
The first approach is called "passing by pointer"; the second approach is called "passing by reference". In the first case, dereference is explicit; in the second case, dereference is implicit.
The biggest difference between the two approaches is that when you pass by pointer, you can pass "nothing" (i.e. a null pointer). When you pass by reference, it is not possible to legally pass a reference to nothing: it should be a reference to some variable, an array element, a field of a class or a structure, etc.
When you need to return a value and modify a variable, passing by reference is more appropriate, because the variable that you need to modify always exists. Passing by pointer becomes more appropriate in situations when you traverse a dynamic data structure connected by pointers, when parts of that data structure may or may not exist.
The you first function foo, you are passing by reference :
When a variable is passed by reference we are not passing a copy of its value, but we are somehow passing the variable itself to the function and any modification that we do to the local variables will have an effect in their counterpart variables passed as arguments in the call to the function.
An example of passing by reference :
In your second example oof, you are passing a pointer to the variable.
If you want to know the different between both example, I suggest you to read this : https://stackoverflow.com/a/57492/1394283
But, When you should use references and when you should use pointer ?
I will say use references whenever you can, use pointers whenever you must.
The reason is that pointers makes things harder to follow/read, less safe and far more dangerous manipulations than any other constructs.
This post explains it very well : https://stackoverflow.com/a/7058373/1394283

Parameter to a function in C++ [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
const CFoo &bar() const
Which is the meaning of this line?
virtual void Encode (KDataStream & stream) const;
What´s the meaning of const at the end in C++?
Which is the meaning of this line?
virtual void Encode (KDataStream & stream) const;
It's a statement that declares a function.
virtual means it's a member function that can be overridden by a function of the same name and compatible parameter and return types declared in a class derived from this one. The correct version will be chosen (at run-time, if necessary) according to the type of the object it's invoked on.
void means it doesn't return anything.
Encode is the name of the function.
( marks the start of the parameter list.
KDataStream is the type of the first parameter.
& means the parameter is passed by reference.
stream is the name given to the parameter; it serves as documentation, but can be left out of the declaration without changing the meaning.
) marks the end of the parameter list.
const means that it's a member function that can't modify non-static, non-mutable data members of the object it's invoked on. It also allows it to be invoked on objects that are declared const.
; marks the end of the statement.
It means -- pass by reference.
The 'const' at the end of the method says that the method implementation will not change the values of any member variables. So, by seeing this in the class interface itself (without having to know the implementation), the clients of the object can know about this behaviour.
Read up on pointers, if you want to code in c++ you will need to know how these work:
http://www.cplusplus.com/doc/tutorial/pointers/
& means you are passing in the memory address of stream rather the value of stream

Use of the & operator in C++ function signatures

I'm currently reading through Accelerated C++ and I realized I don't really understand how & works in function signatures.
int* ptr=&num;
means that ptr now holds the address to num, but what does that mean?
void DoSomething(string& str)
from what I understand that is a pass by reference of a variable (which means passing the address) but when I do
void DoSomething(string& str)
{
string copy=str;
}
what it creates is a copy of str. What I thought it would do is raise an error since I'm trying to assign a pointer to a variable.
What is happening here? And what is the meaning of using * and & in function calls?
A reference is not a pointer, they're different although they serve similar purpose.
You can think of a reference as an alias to another variable, i.e. the second variable having the same address. It doesn't contain address itself, it just references the same portion of memory as the variable it's initialized from.
So
string s = "Hello, wordl";
string* p = &s; // Here you get an address of s
string& r = s; // Here, r is a reference to s
s = "Hello, world"; // corrected
assert( s == *p ); // this should be familiar to you, dereferencing a pointer
assert( s == r ); // this will always be true, they are twins, or the same thing rather
string copy1 = *p; // this is to make a copy using a pointer
string copy = r; // this is what you saw, hope now you understand it better.
The & character in C++ is dual purpose. It can mean (at least)
Take the address of a value
Declare a reference to a type
The use you're referring to in the function signature is an instance of #2. The parameter string& str is a reference to a string instance. This is not just limited to function signatures, it can occur in method bodies as well.
void Example() {
string s1 = "example";
string& s2 = s1; // s2 is now a reference to s1
}
I would recommend checking out the C++ FAQ entry on references as it's a good introduction to them.
https://isocpp.org/wiki/faq/references
You shouldn't know anything about pointers until you get to chapter 10 of Accelerated C++ !
A reference creates another name, an alias, for something that exists elsewhere. That's it. There are no hidden pointers or addresses involved. Don't look behind the curtain!
Think of a guy named Robert
guy Robert;
Sometimes you may want to call him Bob
guy& Bob = Robert;
Now Bob and Robert both refer to the same guy. You don't get his address (or phone number), just another name for the same thing.
In your function
void DoSomething(string& str)
{
  string copy=str;
}
it works exactly the same, str is another name for some string that exists somewhere else.
Don't bother with how that happens, just think of a reference as a name for some object.
The compiler has to figure out how to connect the names, you don't have to.
In the case of assigning variables (ie, int* ptr = &value), using the ampersand will return the address of your variable (in this case, address of value).
In function parameters, using the ampersand means you're passing access, or reference, to the same physical area in memory of the variable (if you don't use it, a copy is sent instead). If you use an asterisk as part of the parameter, you're specifying that you're passing a variable pointer, which will achieve almost the same thing. The difference here is that with an ampersand you'll have direct access to the variable via the name, but if you pass a pointer, you'll have to deference that pointer to get and manipulate the actual value:
void increase1(int &value) {
value++;
}
void increase2(int *value) {
(*value)++;
}
void increase3(int value) {
value++;
}
Note that increase3 does nothing to the original value you pass it because only a copy is sent:
int main() {
int number = 5;
increase1(number);
increase2(&number);
increase3(number);
return 0;
}
The value of number at the end of the 3 function calls is 7, not 8.
It's a reference which allows the function to modify the passed string, unlike a normal string parameter where modification would not affect the string passed to the function.
You will often see a parameter of type const string& which is done for performance purposes as a reference internally doesn't create a copy of the string.
int* ptr=&num;
1st case: Since ptr is a memory and it stores the address of a variable. The & operator returns the address of num in memory.
void DoSomething(string& str)
2nd case: The ampersand operator is used to show that the variable is being passed by reference and can be changed by the function.
So Basically the & operator has 2 functions depending on the context.
While pass by reference may be implemented by the compiler by passing the address as a pointer, semantically it has nothing to do with addresses or pointers. in simple terms it is merely an alias for a variable.
C++ has a lot of cases where syntax is reused in different contexts with different semantics and this is one of those cases.
In the case of:
int* ptr=&num;
you are declaring a variable named ptr with a type of an int * (int pointer), and setting its value to the "address of the variable num" (&num). The "addressof" operator (&) returns a pointer.
In the case of:
void DoSomething(string& str)
you are declaring the first parameter of the DoSomething() method to be of type "reference to string". Effectively, this is the C++ way of defining "pass-by-reference".
Note that while the & operator operates similarly in these cases, it's not acting in the same way. Specifically, when used as an operator, you're telling the compiler to take the address of the variable specified; when used in a method signature, you're telling the compiler that the argument is a reference. And note as well, that the "argument as a reference" bit is different from having an argument that is a pointer; the reference argument (&) gets dereferenced automatically, and there's never any exposure to the method as to where the underlying data is stored; with a pointer argument, you're still passing by reference, but you're exposing to the method where the variable is stored, and potentially exposing problems if the method fails to do a dereference (which happens more often than you might think).
You're inexplicitly copy-constructing copy from str. Yes, str is a reference, but that doesn't mean you can't construct another object from it. In c++, the & operator means one of 3 things -
When you're defining a normal reference variable, you create an alias for an object.
When you use it in a function paramater, it is passed by reference - you are also making an alias of an object, as apposed to a copy. You don't notice any difference in this case, because it basically is the object you passed to it. It does make a difference when the objects you pass contain pointers etc.
The last (and mostly irrelevent to your case) meaning of & is the bitwise AND.
Another way to think about a reference (albeit slightly incorrect) is syntactic sugar for a dereferenced pointer.