Making changes to object state from within a function - c++

I have had to simplify some of my code to ask this question. However, in the below code does the fact that I am not declaring x as a reference type mean my change of decrementing will get "forgotten" once the function has exited?
The smartest way to fix this would be to declare x as AnotherClass& x?
void MyClass::myFunc(unordered_map<int, AnotherClass>* dictionary, int z, int y){
AnotherClass x = dictionary->at(z);
//Does this change on x get "forgotten" in terms of what dictionary stores
//once myFunc() has finished, because x is not a reference/pointer type?
x.changeSomething(y--);
}
class MyClass{
public:
private:
myFunc(unordered_map<int, AnotherClass>* dictionary, int z);
unordered_map<int, AnotherClass>* dictionary
};

Correct. x is a copy of an element of dictionary. You are applying changes to the copy, which is local to the function. You should see no effects in the caller side. You can either take a reference, or act directly on the result of the call to at:
dictionary->at(z).changeSomething(z--);
Note that this has nothing to do with the code being inside a function.

In languages like Java or C# when you write Thing t = s; you are actually creating an alias t that refer to the same object in memory than s refer to. In C++, however, values and aliases are strictly separated:
Thing t = s; is about making a copy of s
Thing& t = s; is about creating an alias referring to the same object than s (a reference)
Thing* t = &s; is about creating an alias referring to the same object than s (a pointer)
The difference between references and pointers does not matter here, what matters is the difference between copies and aliases.
Changes to a copy are local to that copy
Changes to an object via an alias are local to that object, and visible through all aliases referring to that object
In term of your example:
// Fix 1: take dictionary by *reference* and not by *pointer*.
void MyClass::myFunc(std::unordered_map<int, AnotherClass>& dictionary, int z, int y){
// Fix 2: dictionary.at(z) returns a "AnotherClass&"
// that is an alias to the element held within the dictionary.
// Make sure not to accidentally make a copy by using that "&"
// for the type of x.
AnotherClass& x = dictionary.at(z);
// "x" is now a mere alias, the following call is thus applied
// to the value associated to "z" within "dictionary".
x.changeSomething(y--);
}
Note that you could write dictionary.at(z).changeSomething(y--); in this case; however there are several shortcomings:
if x is reused more then once, naming it makes it clearer.
in cases where the function/method invoked have side-effects, the number of calls is important and need be controlled.
from a performance point of view, avoiding unnecessary computing the same thing over and over is always welcome... but don't get too hang up on performance ;)

Related

Why, or in what situations, would you pass an argument to a function as a reference (or pointer) in C++?

I am used to passing arguments regularly in my own code but frequently stumble upon function arguments being passed by reference or pointer while reading over others' C++ code. I do not understand what is the purpose of doing so. Can somebody please explain this?
There are essentially three reasons why this is done.
Reduced memory usage
Every time you call a function the arguments are copied and passed. This isn't a big deal when you are passing around numbers. However when you are dealing with big chunks of memory, like objects, structs, arrays etc. this becomes very expensive.
So all complex types are typically passed as pointers. If you are throwing around objects you are always working with a pointer.
The const qualifier should be used in this instance to indicate that the variable won't be changed.
Modify the argument
Sometimes it is useful to modify the passed argument, though this should be avoided as bad style. The best example I think is modifying an array, for example a push() function. Another is modifying an objects public members, or when you want to return multiple values from a function.
Note that this can be a source of bugs. If you are modifying a passed variable it should be obvious from the name of the function that this is what you are doing.
Low level memory access
Anything which directly works with memory will want direct access to said memory. Standard practice in C but less common in C++. Look at functions like memcpy() and anything else from <string.h>.
If I pass a bunch of characters to a function, I can change them inside it and they will remain unchanged outside the function. This means if you wish to capitalise some text, you'd have to make a copy of it, then change some of the letters.
If on the other hand, you told the function the address of that string in memory, it could then change the existing string without making a copy. Sometimes, the arguments required will consume a trivial size. Other-times, the data required make take several hundred mega/giga/tera bytes. The last thing you want to do is read all that in, then make a copy of it that you can send off to a function.
The difference between references and pointers is mostly convenient syntax for the programmer, but there are important exceptions to this rule.
If you pass argument to a function, you can change it inside the function. Once the execution of that function has finished, the passed in variable will rename unchanged.
int square_this_number(int x)
{
int y = 0;
y = x * x;
x = 1000;
return y;
}
int a = 10;
int b = 0;
b = square_this_number(a);
/* a is still 10, not 1000. */
/* b is 100. */
Pass by reference or pass by pointer means that you want to keep the change once the execution of function has finished.
int try_square_and_change_input(int& x)
{
int y = 0;
y = x * x;
x = 23;
return y;
}
int a = 5;
int b = 0;
b = try_square_and_change_input(a);
/* a is now 23 instead of just 5. */
/* b is 25 of course. */
You may refer to this page: https://www.ibm.com/support/knowledgecenter/en/SSLTBW_2.3.0/com.ibm.zos.v2r3.cbclx01/cplr233.htm
Reasons to do this include:
I need to modify a variable that is not local to the called function.
I want to pass a single word to the function, rather than make a copy of a large structure or array (and possibly another if I need to modify it).
It's a pointer to shared memory and I want changes to be visible in different processes or threads.
It's a pointer to a polymorphic struct or union (or class in C++) and I want the function to be able to determine the correct type at runtime.
The size and type of the data might vary, as with memcpy().
The type should be opaque to client code.
That's just how the interface is specified.
Pass by value: when we don't want to change variables value from called function.
Pass by reference: (only. In c++, not in c): when we want to do changes in variabe by called function.
Pass by pointer: from periferi it works same as reference, but there exist differences..

When is a reference variable appropriate and why? Can you explain the actual syntax and placement? [duplicate]

This question already has answers here:
Why should I use reference variables at all? [closed]
(8 answers)
Closed 5 years ago.
I am brand new to C++. We have recently begun exploring reference variables in class, and I am very confused about them. Not necessarily how to do them, as I understand that they switch variable values, but more along the lines of WHY a developer would want to do such a thing? What do they accomplish? Do they save memory? Do they avoid having to return information?
Here is part of the project we are working on. We need to include at least one reference variable. I can see how I would write the program without the reference variable, but I don't see where a reference variable would be useful or necessary.
"The user may wish to get an estimate for one to many rooms. The rates are based on the square footage of the walls and/or ceiling. The company estimates that it takes 2.5 hours to paint 200 SF of wall space and 3.2 hours to paint the same area on a ceiling. The labor rate is $40 per hour. If the job for painting WALLS totals more than 1400 SF of space, then the customer receives a 15% discount for all square footage above 1400 square feet. There is no discount for painting ceilings.
The program shall print out a final report of the estimated costs in a professional format.
The program shall ask the user if they want to make more calculations before exiting."
I'm not looking for you guys to do my homework for me, and for reference, we have only just finished with learning functions. I'm pretty good, but there are a LOT of things reading through these sites that I do not understand.
And, essentially, studentID would be set to 21654. Am I understanding this correctly?
Let us try this again:
I have reviewed this suggested duplication. While it does cover the basics of the pros/cons of using reference variables instead of pointers and discusses multitudes of reasons for using both, I am still questioning the basic idea of when (when is is appropriate vs. not necessary) and why (why is appropriate in certain circumstances, what advantages does it give to the program?)
I should use such variables as well as how (the actual syntax and placement). Almost everyone here has been great, and I have learned so much on the subject through my interactions with you. Even as much of this is repetitive and irritating to seasoned coders, it is all new to me, and I needed to be involved in the conversation as much as I needed the information. I have used Stack Overflow for many projects, learning about Java's newString.equalsIgnoreCase(), for instance, and I admire your knowledge. I can only tell you the truth, if that is not good enough then it is what it is.
Alright, let me review my understanding so far:
Reference variables tend to cut down on unwanted modification of variables within a function and/or program.
Reference variables are used to modify existing variables within functions
This is useful as it "moves" values around while minimizing copying of those values.
Reference variables modify existing variables within functions/programs
I don't know if you guys can still read this or not since it has been flagged a duplicate. I've been playing with a few of the mini-programs you guys have given me, re-read portions of my book, done further research, etc., and I think I understand on a rudimentary level. These reference variables allow you to alter and/or use other variables within your code without pulling them directly into your code. I can't remember which user was using the foo(hubble, bubble) example, but it was his/her code that finally made it click. Instead of just using the value, you are actually using and/or reassigning the variable.
A reference variable is nothing but an alias name of the variable. You would use it when you wanted to just pass the value around instead of copying the same variable into memory at a different location. So, using reference, copy can be avoidable which saves the memory.
According to Bjarne Stroustrup's FAQ:
C++ inherited pointers from C, so I couldn't remove them without
causing serious compatibility problems. References are useful for
several things, but the direct reason I introduced them in C++ was to
support operator overloading. For example:
void f1(const complex* x, const complex* y) // without references
{
complex z = *x+*y; // ugly
// ...
}
void f2(const complex& x, const complex& y) // with references
{
complex z = x+y; // better
// ...
}
More generally, if you want to have both the functionality of pointers
and the functionality of references, you need either two different
types (as in C++) or two different sets of operations on a single
type. For example, with a single type you need both an operation to
assign to the object referred to and an operation to assign to the
reference/pointer. This can be done using separate operators (as in
Simula). For example:
Ref<My_type> r :- new My_type;
r := 7; // assign to object
r :- new My_type; // assign to reference
Alternatively, you could rely on type checking (overloading). For
example:
Ref<My_type> r = new My_type;
r = 7; // assign to object
r = new My_type; // assign to reference
Also, read this Stack Overflow question about the differences between a pointer variable and a reference variable.
I will give three reasons, but there are many more.
Avoiding unnecessary copies.
Suppose you write a function like so:
double price(std::vector<Room> rooms)
{
...
}
Now, every time you call it, the vector of Room will be copied. If you only compute the prices of a few rooms that's fine, but if you want to compute the cost of repainting the entirety of the offices of the Empire State Building, you will start to copy huge objects, and this takes time.
It is better in this case to use a constant reference that provides read-only access to the data:
double price(const std::vector<Room>& rooms) { ... }
Using polymorphism
Suppose you now have different types of rooms, perhaps a CubicRoom and a CylindricalRoom, that both inherit from the same base class, Room.
It is not possible to write:
double price(Room room) { ... }
and then call
price(CylindricalRoom());
//or
price(CubicRoom());
but you can if you define price as follows:
double price(Room& room);
Everything then works the same as if you passed by value.
Avoiding returns
Suppose that each time you compute a price, you want to add a formatted quote to a report. In C++ you can only return a single object from a function, so you can not write:
return price, fmtQuote
However, you can do:
double price(Room room, std::vector<std::string>& quotes)
{
...
quotes.push_back(fmtQuote);
return price
}
Obviously, you could return a pair of objects std::pair<double, std::string>, but this means that the caller has to unpack the result. If you intend to call often the above function, this will quickly become ugly. In this case, this ties in to the first point: the log of all quotes will grow, and you do not want to copy it for each call.
This is a typical access pattern for shared resources: you want a few functions/objects to get a handle on a resource, not a copy of that resource.
You're mixing up two completely separate things here. Three examples to show how the two things work, individually and then together...
A function can take a parameter passed by value, and return a value.
double foo (double y)
{
y = y + 200.0;
return y;
}
void main(void)
{
double hubble = 50.0;
double bubble = 100.0;
hubble = foo(bubble);
std::cout << "hubble=" << hubble << ", bubble=" << bubble << std::endl;
}
Note that because this is passed by value, even though foo() changes y, bubble does not change. hubble is set to the value returned by foo().
Then you get
hubble=300, bubble=100
A function can take a parameter passed by reference, and modify that parameter.
void foo (double& y)
{
y = y + 200.0;
}
void main(void)
{
double hubble = 50.0;
double bubble = 100.0;
foo(bubble);
std::cout << "hubble=" << hubble << ", bubble=" << bubble << std::endl;
}
Then you get
hubble=50, bubble=300
Of course hubble hasn't changed. But because bubble was passed by reference, the change to y inside foo() changes bubble, because that change is happening on the actual variable passed and not on a copied value.
Note that you do not have a "return" statement here. The function does not return anything - it simply modifies the variable which is passed to it.
And of course you can use both together.
double foo (double& y)
{
y = y + 200.0;
return y + 400.0;
}
void main(void)
{
double hubble = 50.0;
double bubble = 100.0;
hubble = foo(bubble);
std::cout << "hubble=" << hubble << ", bubble=" << bubble << std::endl;
}
Then you get
hubble=700, bubble=300
As before, changing y inside foo() changes bubble. But now the function is returning a value as well, which sets hubble.
Why would you choose to return a value, or to modify the value passed in, or to do both? That entirely depends on how you write your code.
I agree with you that you don't have to use a pass-by-reference here. Myself, I'd probably just return a value. But this is a learning exercise, and you've been told to do it that way, so you've got to. Suppose your pass-by-reference is the discount? So a function "void discount(double& value)" takes the value passed and multiplies it by 0.85. It's a bit artificial, but it would demonstrate the principle.
Reference variables are a safer alternative to pointers. Usually, when dealing with pointers you don't really care about the pointer (ptr) so much as what it points to (*ptr); and yet, all the time programmers screw up and manipulate ptr instead of *ptr and so on. Consider this code:
void zeroize_by_pointer(int* p)
{
p = 0; // this compiles, but doesn't do what you want
}
Compare to the reference version,
void zeroize_by_reference(int& p)
{
p = 0; // works fine
}
There are many other reasons why references are a good idea, but for someone starting out in C++ I'd suggest focusing on this one: it makes it slightly harder to shoot yourself in the foot. Whenever you deal with pointers you're going to be dealing on some level with the machine's memory model, and that's a good thing to avoid when possible.
There is another, more general advantage of references that pointers do not provide. References by their very nature allow you to express through the function signature that the object referred to must exist at the time the function is called No nulls allowed.
The caller cannot reasonably expect a function that takes a reference to check the validity of that reference..
Pointers, on the other hand, may validly be null. If I write a function that accepts a pointer...
void increment(int* val)
{
(*val)++;
}
...and the caller supplies null, my program is probably going to crash. I can write all the documentation I want stating that the pointer must not be null but the fact is it's pretty easy for someone to pass it in accidentally. So if I want to be safe, I must check for it.
But write this function with a reference and the intent is clear. No nulls allowed.
References were introduced primarily to support operator overloading. Using pointers for "passing via reference" would give you unacceptable syntax according to Bjarne Stroustrup. They also allow aliasing.
In addition, they allow object-oriented programming with a nicer syntax than using pointer explicitly. If you are using classes you must pass references to avoid object slicing.
In summary, you should always prefer using references over bare pointers.
You could almost always use reference variables (instead of ever passing by value): for example ...
// this function creates an estimate
// input parameter is the Rooms to be painted
// passed as a const reference because this function doesn't modify the rooms
// return value is the estimated monetary cost
Money createEstimate(const Rooms& rooms)
{
...
}
// this function adds paint to the rooms
// input parameter is the Rooms to be painted
// passed as a non-const reference because this function modifies the rooms
void paintRooms(Rooms& rooms)
{
...
}
When you pass-by-value instead of pass-by-reference then you implicitly create and pass a copy of the thing ...
// creates and passes a copy of the Rooms to the createEstimate function
Money createEstimate(Rooms rooms)
{
...
}
... which (creating a copy) is (often, slightly) slower than passing by reference (furthermore, creating a copy may have side-effects).
As a possible slight performance optimization, and by convention (because people don't care), it's common to pass-by-value instead of pass-be-reference when the type is small and simple (a.k.a. a "primitive" type), for example:
// passes a copy of the x and y values
// returns the sum
int add(int x, int y)
{
...
}
... instead of ...
// passes a reference to x and y
// returns the sum
int add(const int& x, const int& y)
{
...
}
See also Passing a modifiable parameter to c++ function as well as Why have pointer parameters?
There are also different kinds of references. We have lvalue and rvalue references, designated by & and &&, respectively. Generally, a reference tells us something about the lifetime of the object it references, a pointer does not. Compare
void foo(int* i);
void foo(int& i);
void foo(int&& i);
In the first case, i might point to an object we can assign to, but more importantly, it may also be a nullptr or point to one-past-the-end of an array. Thus, dereferencing it may lead to undefined behaviour. Checking for a nullptr is easy enough, the other check is not.
The the second case and third case, i must always reference an valid int we can assign too.
The difference between rvalue and lvalue references is that rvalue/&& references convey the meaning that the referenced value is not needed by anyone else and as such, allows for optimizations. Read up on std::move and move constructors to see what I mean.
To summarize: references tell us something about the object's lifetime. Sure, this could be stated in the documentation, but with pointers, violations of that contract might be hard to catch. References enforce the contract (to a high degree) at compile time and as such provide documentation to the code implicitly. This allows for some quick, uncomplicated optimizations by using e.g. move constructors or perfect forwarding in some cases.
Reference arguments are more used when you pass an object as argument. That way you don't copy the whole variable; usually they come with a const modifier like:
void printDescription(const Person& person) { ... }
That way you don't copy the object.
Sometime the return type is also set as a reference. That way you are returning the same object (and not a copy of it). Have a look at the << operator of ostream. ostream& operator<< (streambuf* sb );.
With variables you can think about the case where you can swap values.
void swap(int & a, int & b) {
int aux = a;
int a = b;
int b = aux;
}
This case in Java, for example, has to be done in a more complex way.
Reference variables are pointers without a * and practically without pointer arithmetics.
They are not needed from the C++, they are only syntactic sugar around them.
The initial idea of the creators was probably to make C++ code better comprehensible, although they reached its exact opposite.
My opinion is that a C++ program is better if it entirely misses reference variables and it uses only pointers.
Your function in the form
double foo (double studentID* y)
{
*y = 21654;
return *y;
}
...would do exactly the same, but it would be actually better comprehensible.

What's the difference between using * and using & in C++ functions?

I am trying to find out using the below code with sort an array in asscending order. And I find method 1,2,3,4 all get the same result:1234.
Which method is the best?
And when and why should should I use pointer /reference? Thanks you.
Using & to call, and * in function parameter
Just used * in function parameter
Just used & in function parameter
nothing:
#include <iostream>
using namespace std;
void swap(int a,int b){
int t;
t=a;
a=b;
b=t;
}
void main(){
int a[]={1,2,3,4};
for (int i=1; i<3; i++)
for (int j=3; j>i;j--)
if(a[j]<a[j-1])
swap(a[j],a[j-1]);
cout << a[0] <<a[1]<<a[2]<<a[3];
}
Your first two versions are identical. They both explicitly pass a pointer in to the function.
Your third version has the same semantics, but different syntax. References can be seen as pointers with nicer syntax.
Your fourth version doesn't actually swap the variables you pass in because you pass by value, so they are copied.
I would prefer the third version as it is clearer.
Generally, references are more of a convenience thing. They allow the programmer to pass objects by reference without explicitly saying they want to do so
For example, this code
// C-style pointers
some_func(int* x, int* y)
{
(*x)++;
(*y)++;
}
...
int x = 5, y = 8;
some_func(&x, &y);
// x == 6 and y == 9
Is effectively equal to this code
// C++-style references
some_func(int& x, int& y)
{
x++;
y++;
}
...
int x = 5, y = 8;
some_func(x, y);
// x == 6 and y == 9
Both achieve the same result.
Also, in the case with classes/structs, references allow you to have direct access to class/struct members without having to type that stupid arrow (->):
class Example
{
public:
Example();
int x;
int y;
}
...
void do_something(Example& ex)
{
ex.x++;
ex.y++;
}
instead of
class Example
{
public:
Example();
int x;
int y;
}
...
void do_something(Example* ex)
{
ex->x++;
ex->y++;
}
Please note that references used in this manner are a C++ feature only (there is no support for this in C). In C++ you have the choice of using either pointers or references, but IMHO references look 'cleaner' and require less typing (thus reducing the risk of RSI).
I don't see a difference between 1. and 2.. But in general:
Passing pointers is passing an address to a variable. Then you modify something under this address using dereference i.e. *a.
Same.
Is passing via reference, it is basically equivalent of passing pointers with nicer syntax. There are of course some "minor" (from a beginner's point of view) differences, such as, you cannot make an empty reference (nullptr).
Is passing by value, which does not operate on original operands but on their copies. At the function call, temporary copies of arguments are made. This means, you won't see changes to the argument outside of the function.
The general order of preference is:
Use references, or const references.
If you need to make a copy of the object anyways, pass by value.
Smart pointers.
Pointers. Normal user should almost never need to resort to this.
Using references is preferred, because c++ prefers value-semantics. In other words, treating things like variables, i.e. not handlers/pointers. So when you pass a variable to a function, you type it naturally, even if you want to change it. You want to use the object, you pass the object. You don't care that under the hood it uses handlers.
Pointers are generally reserved for operations which deal with ownership of objects.
Separating pointers and references in such way makes it possible to express separate semantics with separate syntax. This makes code more readable.
First of all, I would like to point out that you shouldn't have used
int a[]={1,2,3,4};
in your code, because your program will always display 1234 even if your swap function does not work well. Therefore, you should use something like
int a[]={2,4,1,3};
Secondly, method 1 and method 2 are exactly same. There's no difference at all.
Thirdly, method 4 does not work properly, because the data in the array 'a' hasn't been modified. This happens because you have passed the variables 'by value' rather than 'by reference'. You are getting 1234 as output because that's what you have assigned to the array.
Finally, the only choice you have is between 'method 1' and 'method 3'.
I would suggest 'method 3' because it is simpler to use and less prone to confusion (and errors) as compared to 'method 1'.
In some cases, passing by reference allows the compiler to keep a register based variable in that same register in the called function (as opposed to storing the value in local memory and passing an address to that local memory to the called function).

What is the difference between a variable and a reference in C++? [duplicate]

This question already has answers here:
What is a reference variable in C++?
(12 answers)
Closed 8 years ago.
Facts that I have known:
There are three types of variables in C++: variables, pointers and references.
Variables is kinda label for the memory that stores the actual data.
Pointers stored the address of the variables.
References are alias for the variables.
My questions:
By observation, the use of variables names and references is exchangeable. Is that true?
What is the difference between passing a variable name as parameter and passing a reference? e.g.,
void func(int a); vs void func2(int& b);
Thanks a million!
Here is a way to understand the difference:
Objects that can change state are also called "variables".
Pointers are objects (variable or not). They have a state.
References are "nicknames". They don't have a state, but expose the state of the refereed object (which is why you can't re-assign a reference, it's not an actual object).
Now, in some cases references might be implemented as pointers, but from the language point of view, references are just not pointers, they really are additional names for an object already existing.
As pointers are objects, and have a state, passing pointers to functions will copy that state, the pointer's state, not the pointee's state. However, references have no state, so if you pass a reference to a function, it's the refereed object that you pass (by copy).
By observation, the use of variables names and references is
exchangeable. Is that true?
"References are nickname" is the best way to understand references.
What is the difference between passing a variable name as parameter
and passing a reference? e.g.,
void func(int a); vs void func2(int& b);
The first implementation ask for a copy of the object passed. That is, internally func() can do anything to a, without changing the object that was passed to func() because internally func() made a copy of that object and manipulates the copy, not the original.
The second implementation ask for "a nickname for an object already existing". First, the object have to exist and if passed, a nickname for it will be created inside the function. That nickname, the reference b, is still a nickname for the original object. This mean that any manipulation done to b will affect the original object passed to func2().
func() signature says "I need this data but I will not modify the original object passed.".
func2() signature says "I need an object that I WILL certainly modify, pass it so that I can modify it".
Bonus stage:
At this point, if you don't know yet about const, that might be useful: in function signatures const is used with references to specify the arguments that are "read-only".
Let me clarify:
void func3( const int& b);
Here func3 says: "I need to access to an object, but really I will not make a copy of it. However I guarantee that I will not change that object".
So, why would we need that? Because some objects are expensive to copy. int is cheap to copy so most people will just pass it and func() and func3() are basically equivalent (depends on implementation but generally true).
If however we want to pass, says, a very big object, like a data buffer, we really don't want to copy it again and again just to apply some algorithms.
So we do want to pass it by reference. However, depending on the function, sometime you want to extract information and work with it, so you only need "read-only" access to the argument. In this case you use const Object&. However, if you need to apply the algorithm to the object passed, you need to be able to modify it, which you could call "write-access". In this case, you need to use a normal reference.
Asking for a copy basically mean that you want to manipulate an object that is the same state than the passed object, but is not the passed object.
To summarize:
func( T object ) : I want to have a copy of an object of type T;
func( T& object ) : I want to have "write-access" to an object of type T - assume that I will modify that object!;
func( const T& object ) or func( T const & object ) // which are the same : I want to read the state of an object, but I guarantee you that I will not modify it, I want "read-only" access.
Actually, the "read-only" guarantee could be violated using const_cast<> but that's a different story and it's only used in some very very very narrow cases.
Last thing you need to know is that if you have a member function, then you can do:
class K{
public:
void func() const; // see the const?
};
In this specific case, what you say is that inside the function, which is basically equivalent to:
void func( const K* this );
In this case you can see that this is a pointer but it's pointing to a const object. This mean that func() guarantee that the object it is member of (this) is never modified through this function (except some specific cases, see mutable keyword, another long story).
Let's say you have these two functions:
void addone(int a) {
a += 1;
}
void addone_bis(int &a) {
a += 1;
}
If you call the first function in your main function, the value will only change in the function addone and not in the main, whereas if you call addone_bis the value of a will also be changed in the main function.
int main() {
int test_a = 10;
int test_b = 11;
addone(test_a);
// test_a still equals 10.
addone_bis(test_b);
// test_b now equals 12.
}
Did I correctly answer to your question?
Your first example is what is known as PASSING BY VALUE. What this means is that a copy of the ACTUAL value is passed into the routine.
When passing in the way of your second example, this is what is known as PASSING BY REFERENCE. A reference is ESSENTIALLY a passing of the variable into the routine such that its ACTUAL VALUE can be modified by the called routine without DE-REFERENCING.

What is the difference between references and normal variable handles in C++?

If C++, if I write:
int i = 0;
int& r = i;
then are i and r exactly equivalent?
That means that r is another name for i. They will both refer to the same variable. This means that if you write (after your code):
r = 5;
then i will be 5.
References are slightly different, but for most intents and purposes it is used identically once it has been declared.
There is slightly different behavior from a reference, let me try to explain.
In your example 'i' represents a piece of memory. 'i' owns that piece of memory -- the compiler reserves it when 'i' is declared, and it is no longer valid (and in the case of a class it is destroyed) when 'i' goes out of scope.
However 'r' does not own it's own piece of memory, it represents the same piece of memory as 'i'. No memory is reserved for it when it is declared, and when it goes out of scope it does not cause the memory to be invalid, nor will it call the destructor if 'r' was a class. If 'i' somehow goes out of scope and is destroyed while 'r' is not, 'r' will no longer represent a valid piece of memory.
For example:
class foo
{
public:
int& r;
foo(int& i) : r(i) {};
}
void bar()
{
foo* pFoo;
if(true)
{
int i=0;
pFoo = new foo(i);
}
pFoo->r=1; // r no longer refers to valid memory
}
This may seem contrived, but with an object factory pattern you could easily end up with something similar if you were careless.
I prefer to think of references as being most similar to pointers during creation and destruction, and most similar to a normal variable type during usage.
There are other minor gotchas with references, but IMO this is the big one.
The Reference is an alias of an object. i.e alternate name of an object. Read this article for more information - http://www.parashift.com/c++-faq-lite/references.html
A reference is an alias for an existing object.
Yep - a reference should be thought of as an alias for a variable, which is why you can't reassign them like you can reassign pointers (and also means that, even in the case of a non-optimizing compiler, you won't take up any additional storage space).
When used outside of function arguments, references are mostly useful to serve as shorthands for very->deeply->nested.structures->and.fields :)
C++ references differ from pointers in
several essential ways:
It is not possible to refer directly to a reference object
after it is defined; any occurrence of its name refers directly to the
object it references.
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, whereas pointers can; every reference
refers to some object, although it may or may not be valid.
References cannot be uninitialized. Because it is impossible to reinitialize a
reference, they must be initialized as soon as they are created. In particular, local and global variables must be initialized where they are defined, and references which are data members of class instances must be initialized in the initializer list of the class's constructor.
From Here.
The syntax int &r=i; creates another name i.e. r for variable i.hence we say that r is reference to i.if you access value of r,then r=0.Remember Reference is moreover a direct connection as its just another name for same memory location.
You are writing definitions here, with initializations. That means that you're refering to code like this:
void foo() {
int i = 0;
int& r = i;
}
but not
class bar {
int m_i;
int& m_r;
bar() : i(0), r(i) { }
};
The distinction matters. For instance, you can talk of the effects that m_i and m_r have on sizeof(bar) but there's no equivalent sizeof(foo).
Now, when it comes to using i and r, you can distinguish a few different situations:
Reading, i.e. int anotherInt = r;
Writing, i.e. r = 5
Passing to a function taking an int, i.e. void baz(int); baz(r);
Passing to a function taking an int&, i.e. void baz(int&); baz(r);
Template argument deduction, i.e. template<typename T> void baz(T); baz(r);
As the argument of sizeof, i.e. sizeof(r)
In these cases, they're identical. But there is one very important distinction:
std::string s = std::string("hello");
std::string const& cr = std::string("world");
The reference extends the lifetime of the temporary it's bound to, but the first line makes its a copy.