I know there are few question about const correctness where it is stated that the declaration of a function and its definition do not need to agree for value parameters. This is because the constness of a value parameter only matters inside the function. This is fine:
// header
int func(int i);
// cpp
int func(const int i) {
return i;
}
Is doing this really a best practice? Because I've never seen anyone do it. I've seen this quotation (not sure of the source) in other places this has been discussed:
"In fact, to the compiler, the function signature is the same whether you include this const in front of a value parameter or not."
"Avoid const pass-by-value parameters in function declarations. Still make the parameter const in the same function's definition if it won't be modified."
The second paragraph says to not put the const in the declaration. I assume this is because the constness of a value parameter is meaningless as part of a interface definition. It is an implementation detail.
Based on this recommendation, is it also recommended for the pointer values of pointer parameters? (It is meaningless on a reference parameter since you can't reassign a reference.)
// header
int func1(int* i);
int func2(int* i);
// cpp
int func1(int* i) {
int x = 0;
*i = 3; // compiles without error
i = &x; // compiles without error
return *i;
}
int func2(int* const i) {
int x = 0;
*i = 3; // compiles without error
i = &x; // compile error
return *i;
}
Summary: Making value parameters is useful to catch some logic errors. Is it a best practice? Do you go to the extreme of leaving the const out of the header file? Is it just as useful to const pointer values? Why or why not?
Some references:
C++ const keyword - use liberally?
Use of 'const' for function parameters
An example of when const value parameters are useful:
bool are_ints_equal(const int i, const int j) {
if (i = j) { // without the consts this would compile without error
return true;
} else {
return false;
}
// return i = j; // I know it can be shortened
}
I've read many times that making value parameters in a function const is a bad thing to do because it's unnecessary.
However, I find it occasionally helpful to me as a check that my implementation doesn't do something I don't intend (as in the example at the end of your question).
So, while it may not add value to the caller, it does sometimes add a small bit of value to me as an implementer, and it doesn't take anything away from the caller. So I see no harm using it.
For example, I may be implementing a C function that takes a couple pointers to a buffer - a pointer to the start, and a pointer to the end. I'm going to put data in the buffer, but want to ensure that I don't overrun the end. So inside the function there's code that will increment a pointer as I'm adding data to it. Making the pointer to the end of the buffer a const parameter will ensure that I don't code up a bug that accidentally increments the end boundary pointer instead of the pointer I really should be incrementing.
So a fillArray function with a signature like this:
size_t fillArray( data_t* pStart, data_t* const pEnd);
will prevent me from accidentally incrementing pEnd when I really mean to increment pStart. It's not a huge thing, but I'm pretty sure everyone who has programmed for any period of time in C has run across such a bug.
My take on it:
It's not a bad idea, but the issue is minor and your energy might be better spent on other things.
In your question you provided a good example of when it might catch an error, but occasionally you also end up doing something like this:
void foo(const int count /* … */)
{
int temp = count; // can't modify count, so we need a copy of it
++temp;
/* … */
}
The pros and cons are minor either way.
Unfortunately, some compilers (I'm looking at you, Sun CC!) incorrectly differentiate between arguments declared const and ones not declared so, and you can get errors about undefined functions.
I think this is dependent on your personal style.
It doesn't add or subtract to what clients can pass to your function. In essence it's like a compile-time assertion. If it helps you to know that value won't change, go ahead and do it, but I don't see a big reason for others to do it.
One reason I might not do it is that the const-ness of the value parameter is an implementation detail that your clients don't need to know about. If you later (purposely) change your function so that it actually does change that value, you will need to change the signature of your function, which will force your clients to re-compile.
This is similar to why some people recommend having no public virtual methods (the functions virtual-ness is an implementation detail that should be hidden from clients), but I'm not in that particular camp.
If there is const keyword present; it means value of 'i' (which is const type) can not be modified.
If value of 'i' is changed inside foo function compiler will throw error: "
Can not modify const object
But changing '*i' (i.e. *i = 3;)means you are not changing value of 'i' but value of address pointed by 'i'
Actually,the const function is appropriate for large objects that should not be altered by function.
I like const correctness for situations like this:
void foo(const Bar &b) //I know b cannot be changed
{
//do something with b
}
This lets me use b without fear of modifying it, but I don't have to pay the cost of a copy constructor.
Related
When learning C++, one of the first functions one gets for learning the concept of a function is something like
int add(int a, int b)
{
return a+b;
}
Now I was wondering: Should I use the const-keyword here, or rather not, resulting in
int add(const int a, const int b)
{
return a+b;
}
But would that make sense? Would it speed my program up, do some other important stuff, or just increase confusion?
From the caller's perspective, both the first and the second form are the same.
Since the integers are passed by value, even if the function modifies a and b, the modified values are copies of the original and won't be visible to the caller.
However, from the function implementer's perspective there's a difference. In fact, in the second form:
int add(const int a, const int b)
you will get a compiler error if you try to modify the values of a and b inside the function's body, as they are marked as const.
Instead, you can change those values if you omit the const.
Again, those modifications will not be visible to the caller.
If you are actually struggling with correctness bugs in your codebase where const would have helped, then add const.
That said, there are related issues that you should consider. Top-level qualifiers of function parameters aren't part of the function type, so your function type is still just int(int, int). (The qualifiers only affect the parameter variables in the function definition.) That means that any declaration of the function also ignores qualifiers, so int add(int, int) and int add(const int, int) and int add(int, const int) all declare the same function. So you have to decide on a policy for how you write header files. And now you have three essential positions you can take:
Always qualify in both declaration and definition. The upside is that this perhaps keeps code looking "consistent" (think copy/pasting when creating implementations). The downside is that the qualifiers have nothing to do with the interface, and are not at all enforcible (you can change the definition later!), so at best it's noise, at worst it's wrong.
Qualify in the definition, but not in the other declarations. The upside is that this communicates the interface correctly and you still get const checking in the definition. The downside is that some people might be confused by the discrepancies in spelling. (Just like people may be confused that a static constexpr T foo; class member can be defined with const T C::foo;.)
Don't qualify either. The upside is that it's consistent, clean, easy to remember and minimal. The downside is that you're missing out on correctness checks in your definition.
There's no right answer. If you're the codebase owner or project lead, you should decide based on what the biggest problems in your codebase and team are. (My personal position is to stick with (3) until you have a good reason to change.)
Using int add(const int a, const int b) means that you cannot modify the input parameters within the function body.
Perhaps the compiler can make some optimisations based on that, so it ought therefore to be never slower than the non-const equivalent. But I have never observed this effect in practice.
Passing const parameters can also increase the stability of your code base, particularly in a collaborative project.
All this said though, I find it too verbose, rather unnecessary, and would use int add(int a, int b). Very occasionally, for particularly long functions, I exploit the fact that you can declare the function with non-const parameters, and define it with the parameters const.
I feel like everyone is dancing around this part of the answer...
It's true that using const will keep the function from modifying the value of your int a & b while inside the function. This can be extremely useful, so use it as you wish, of the compiler allows it. But, the function caller will never know about any changes to a & b once the function finishes. So even if a & b are changed, no one except the defined function will know their updated values.
int funcB(int a, int b)
{
a = a+1;
b = b*b;
return a+b;
}
void funcA()
{
int s = 5;
int t = 6;
int result = funcB(s, t);
printf("%f + %f = %f", s,t, result);
}
funcA prints: "5 + 6 = 42"
Const protection is often used when passing values by reference, ie:
int function(const int &a, const int &b) {}
This passes a reference of a and b to the function (ie, does not make copies of a and b but passes only a memory address of that variable, aka: the handle). When passing a variable by reference, any changes made to the variable are remembered outside the scope of the function and can change the way your program runs. This is generally undesired behavior.
So if you rework funcB from above and pass by reference:
int funcB(int &a, int &b)
{
a = a+1;
b = b*b;
return a+b;
}
funcA prints: "6 + 36 = 42"
If you add const correctness to funcB:
int funcB(const int &a, const int &b)
{
a = a+1;
b = b*b;
return a+b;
}
I don't think the compiler will let you even do this since you would be explicitly trying to modify values that you've protected via const.
Another time when it may be really important to use const is when you're passing by pointer, instead of reference or copy...
int funcB(int *a, int *b)
{
a = a+1;
b = b*b;
return a+b;
}
Unless you're a pointer expert, avoid passing pointers without const pretention. This func will likely attempt to iterate the index of your pointer arrays and you'd open yourself up to run time errors related to out of bound memory. You could accidently see memory from an entirely different program... but probably not.
Lastly, since you're just passing int, there's no practical need to pass by reference (which is done often to keep from adding complex data into memory because each non-reference or non-pointer pass to functions copies the value into memory for the life of the function being called) since the memory footprint of int is so small. Unless, you're working with specialized hardware that has extremely limited memory, then it may be useful; this won't apply to most standard computers and desktops made within the past 20 years, or smart phones.
int add(const int a, const int b)
{
return a+b;
}
Here const in used so that the function does not modify the original values of a and b by any chance.
In the above example it does not make sense. But if it would have been an example like
int add(const int *a, const int *b)
{
//*a = 10; //This will throw error.
return a+b;
}
In functions where objects,arrays or such data types are passed its a good approach to use const to avoid mutation of original data structure.
If you want to be truly const correct, then you should add it, but in reality all it will do is make you type and read more.
Nothing will go faster, and while it could mean that your variables go into another location in memory, it's unlikely to on most modern machines.
What it will stop you doing is accidentally assigning them values, but as they're local to the function, it's relatively unimportant. What would matter is if they were references, as this demonstrates your intent to the caller to not change them.
You can use const there if you like.
It is unlikely to speed up your program because any reasonable compiler can already see that no code path alters the value of a or b and make any optimisations it needs.
a and b are int, which are passed by value so making them const has no impact on the users of this function.
The only possible advantage is where your function is long and more complex and you want to avoid possible programming errors where the original values of a or b are changed during the function.
If you will use const then you cannot modify the value of a,b. Thats why we don't use const.
The primary purpose of constness is to provide documentation and prevent programming mistakes. Const allows you to make it clear to yourself and others that something should not be changed. Moreover, it has the added benefit that anything that you declare const will in fact remain const short of the use of forceful methods. It's particularly useful to declare reference parameters to functions as const references:
bool SomeFunction (const myObj& obj);
Here, a myObj object is passed by reference into SomeFunction. For safety's sake, const is used to ensure that SomeFunction cannot change the object--after all, it's just supposed to make sure that the object is in a valid state. This can prevent silly programming mistakes that might otherwise result in damaging the object (for instance, by setting a field of the class for testing purposes, which might result in the field's never being reset). Moreover, by declaring the argument const, users of the function can be sure that their object will not be changed and not need to worry about the possible side effects of making the function call.
moreover, The reason is that const for the parameter only applies locally within the function, since it is working on a copy of the data. This means the function signature is really the same anyways. It's probably bad style to do this a lot though. I personally tend to not use const except for reference and pointer parameters.
as a law of thumb we are advised to use const as much as possible because we get a great help from the compiler so whenever we try to change a constant the mistake will be caught by the compiler; it's a good thing avoiding being caught in error-prones.
the second thing: a and b passed by value so they are created as local constants But as long as they are not changeable why we need copies??
the good thing is to pass a const reference which means never change parameters and avoid copies (by value):
int add(const int& a, const int& b) // now there are no copies of a and b in addition we cannot modify a and be
{
return a+b;
}
I was watching a video and saw this code:
class Dog {
public:
Dog() : age(3), name("dummy") {}
void setAge(const int &a) { age = a; }
private:
int age;
std::string name;
};
I was curious about the function signature for setAge because I've never used const as a function parameter. I've looked at several related answers, but none that seemed to answer my question.
In such an elementary example, it's hard to see the benefit of passing a const reference to a function.
Is there any reason why you'd want to make the reference a const? The only application I could think of is in embedded programming when making a copy of a variable could waste precious space.
Are there any simple examples, perhaps, where the impact is seen easily of passing a const reference?
Consider the following three examples:
(i) void setAge(int &a) { age = a; }
(ii) void setAge(const int &a) { age = a; }
(iii) void setAge(int a) { age = a; }
Further think of your class as an encapsulated object, that is the outside world in general doesn't know what's going on inside.
Then, using case (i), the caller cannot know that a has not been changed afterwards.
int a=3;
dog.setAge(a); //case (i): what is "a" afterwards?
One does not know what value a holds after the function call -- in fact, the function signature tells the caller that a change of a is likely to occur.
On the other hand, by using variant (ii), you again pass the object via reference, that is you do not make a copy, but tell the function the memory address where it can go to accss the parameter. In contrast to case (i), now you ensure the caller "nothing is going to happen to your parameter". That is, you can safely work with the parameter afterwards and be assured it has still the same value as before (--at least in principle, as also bad things like a const_cast might happen inside the function).
Finally, in case (iii), one makes a copy of the int and uses that inside the function. For built-in types like int, that is in fact the preferred way to pass function parameters. However, it might be uneffective if the object is expensive-to-copy.
With regard to the whole const correctness-topic, see here.
Making a copy of a variable wastes precious space and wastes precious time, which is why avoiding unnecessary copies is something to worry about in any kind of programming, not just embedded one. For this reason using const T & references for passing read-only parameters has always been an idiom in C++.
However, it is usually reserved for passing in "heavy" objects, i.e. objects that that are relatively expensive to copy. Using it with scalar types (as in your example) makes little or no sense.
Consider an object which has a large memory footprint. You need to pass it to a function - a function which will only extract some information without changing the object in anyway possible. A const reference is a good candidate in such a case.
std::vector can be an example, a Matrix object is another example.
void setAge(const int &a) { age = a; }
You are passing a const int reference, you don't intend to modify the value a inside function setAge.
void setAge(int &a) { age = a; }
You are passing a int reference, you don't care does function setAge modify the value a inside function setAge.
Doing const correctness is a good programming practice here as a practice of better interface definition. First function signature convey the message very clearly, and second one is vague compared to first one.
You can read more about const correctness here https://isocpp.org/wiki/faq/const-correctness#overview-const
according to some tutorials i read a while back, the "const" declaration makes a variable "constant" ie it cannot change later.
But i find this const declaration abit inconveniencing since the compiler sometimes gives errors like
"cannot convert const int to int"
or something like that.
and i find myself cheating by removing it anyway.
question:
assuming that i am careful about not changing a variable in my source code, can i happily forget about this const stuff?
Thanks in advance
Are you serious? Why would you want to give up on such a useful feature just because you make a mistake sometimes? Better try and learn to avoid mistakes with const and you benefit from the great assistance it adds to ensure correctnes with your code.
Of course, you can say goodbye to all the help the language provides, and tell the compiler thereby not tell you about mistakes in your code anymore. Instead, you will have to ask the debugger later on where your bugs are. Not sure whether that's better.
In C++, "const" can a apply to a variable (making it unchangeable) or a function (rendering it unable to change other things).
My use of "const" is not just to prevent my code from changing my variable. It's to prevent some idiot's code from changing my variable (especially if the idiot is me six months from now) and to prevent my code from changing a critical variable some idiot left exposed (especially if the idiot was me six months ago).
If you are careful, yes. But it is human to err. Also, you do not give the compiler the opportunity to optimize around these constants.
The error message that you get is because you try to alter a const int. Simply assigning the value to a (non-const) int, you alter it as you want to.
Const helps you, try to sprinkle more of it around and listen to the compiler. That will help you produce better code.
Even if you and everyone you work with never makes mistakes, the use of const in your method declarations helps to document your interface.
You lose some useful language features without const, especially regarding references. Consider:
void f(const MyClass& m);
void f(const int& i);
// ...
f(MyClass()); // OK, can pass temporary as const reference
f(5); // OK as well, 5 is a temporary int
If you consider the 'const' optional and get rid of it:
void f(MyClass& m);
void f(int& i);
// ...
f(MyClass()); // Error, cannot pass temporary as non-const reference
f(5); // Error, same as above
The idea behind using 'const' is specifically that you ensure compiler errors when attempting to alter a variable's value when it has been predetermined (by using const) that you do NOT want to do so. It's essentially built in error-checking, and is useful for many reasons.
This is especially valuable in cases such as an external interface and public methods as a way of guaranteeing the caller that a passed value will not be modified.
const also locks in the intent to not modify, and prevents accidental assignment.
While making const use mandatory is unnecessary, it is very useful and good practice.
Here's a useful explanation you may want to check out: http://duramecho.com/ComputerInformation/WhyHowCppConst.html
You can forget about it but isn't it nice if the compiler forces it upon you? That way, your "const" variables actually stay constant.
Its always optional. If its all your code sure you can forget it ( I wouldn't recommend it, because it protects you), but when you interact with others, you're essentially providing a contract for them that you won't change their object or calling a function does not change the state of your object. This can be invaluable when you are not familiar with other's code, or you don't have the source.
To answer your question first:
Yes, you can. But only if you are careful, and everyone else who uses your code from now to eternity is also careful.
So, on balance you are better off thinking about why you should make something const and when you should not.
Another technique for exploring why const makes a difference is to try to make everything const at first until you have valid reasons to change something, then, and only then, remove the minimum number of consts until it works again.
Glad to see you are thinking about the issue - its more than most do.
People usually face this problem when they start using the const keyword. Believe me, it really helps. Leave it to the compiler to take care of the cosntness of the variable, instead of you taking care to not alter its value anywhere.
Changing things that shouldn't be changed is one of the most common sources of error.
It is therefore worthwhile specifying const because it prevents you from doing something wrong. Why would you want to give that up?
const double PI = 3.14159265358979;
PI=4; // generates a compiler error (good)
There are some problems with the c++ notation, because a constant can only be initialized, not assigned the first time, and sometimes, you don't have the value at initialization time.
class A {
private:
const int num;
public:
A(int x, int y) : num(0) { // oops, I don't yet know what num should be
while ( ... ) {
}
num = ...;
}
};
The way out of this one is to define a private function that computes the value of num
but sometimes that means that instead of one clean block of code in the constructor, you are forced to split it into sections in awkward ways, just so you can initialize the variable.
class A {
private:
const int num;
int computeNum(int x, int y) { ... }
public:
A(int x, int y) : num(f(x,y)) {
}
};
Sometimes, you have a value that is generally supposed to be const, but you want to selectively override that when it semantically makes sense. For example, social security numbers don't change, unless your identity is stolen. So you have just one method, called createNewSSN() which changes the otherwise constant ssn
class Person {
private:
const int ssn;
public:
Person(int ssn_) : ssn(ssn_) {}
void createNewSSN(int newssn) {
log << "Changed SSN: " << ssn << " to " << newssn << "\n";
*(int*)&ssn = newssn; // trust me, this is a special case....
}
};
I have this snippet of code here. The intention is to make a copy of initialData. Since I am not modifying initialData in any way, I figure that I should pass it as a const reference. However, I keep getting this message when compiling.
.\src\Scene\SceneAnimationData.cpp(23)
: error C2662:
'SceneTrackerData::getRect' : cannot
convert 'this' pointer from 'const
SceneTrackerData' to 'SceneTrackerData
&'
#include "SceneTrackerData.h"
void SceneAnimationData::SetupData(const SceneTrackerData &initialData)
{
// getRect(), points() and links() all return const pointers
CloneRect(initialData.getRect());
ClonePoints(initialData.points()->values());
CloneLinks(initialData.links()->values());
}
void SceneAnimationData::CloneRect(const QGraphicsRectItem * initialRect)
{
if (initialRect != NULL)
{
QPointF position = initialRect->scenePos();
QRectF rect = initialRect->rect();
initialRect = new QGraphicsRectItem(rect);
initialRect->setPos(position);
}
}
void SceneAnimationData::CloneLinks(const QList<QGraphicsLineItem*> links)
{
links_ = new QList<QGraphicsLineItem*>(*links);
}
void SceneAnimationData::ClonePoints(const QList<QGraphicsEllipseItem*> points)
{
points_ = new QList<QGraphicsEllipseItem*>(*points);
}
Without the definition of SceneTrackerData, it's hard to say, but likely that function (SceneTrackerData::getRect) is not marked as const.
That is, what is (guessing):
const Rect& SceneTrackerData::getRect(void)
Should be:
const Rect& SceneTrackerData::getRect(void) const
// ^
// |
// does not logically modify the object
It's not clear which is line 23 here; but my guess is that you are calling methods on the object that are not themselves declared as const and thus are not usable by a const object reference.
I am thinking lines like these are illegal:
links_ = new QList<QGraphicsLineItem*>(*links);
points_ = new QList<QGraphicsEllipseItem*>(*points);
in that the passed in links and points are not defined as pointers, but defined values. In order to compile the code, You probably need to either define them like this
const QList<QGraphicsLineItem*>* links
or, instead use them like this
links_ = new QList<QGraphicsLineItem*>(&links); // don't actually do this
However the latter one is potentially a run-time bug, because you are accessing the address of a temp value, which dies after the function body.
Unless QList uses a deep-copy, your app may very likely crash.
I'm not sure as I am no expert C++ programmer, but are your functions getRect() and so on declared const? If not but you know the way you use them is const, you can still use a const_cast to remove the const from your initialData reference.
See for example here: http://docs.oracle.com/cd/E19422-01/819-3690/Cast.html
Or Scott Meyers excellent C++-Books Effective C++ and More Effective C++. At least one of them has an item about constness.
links_ = new QList<QGraphicsLineItem*>(*links);
This could potentially be legal if the * operator is overloaded for the QList class, though I don't think it is. Although as mentioned above, you're probably trying to do
links_ = new QList<QGraphicsLineItem*>(links);
Depending on what the actual constructor takes.
Also, each of those functions should take in the QList by reference, for performance reasons. Right now you copy the entire object twice for each time you call the function. Once to pass it in by value, then once for the construction of the copy.
One thing to remember when dealing with const'ness is that const is NOT guaranteed. Structures exist such as "const_cast" to strip away the const'ness of an object. Having a const object, and using const functions is helpful to signify to other developers that the code should not change the object, not that it cannot change it. See the difference?
void bar(const Foo& f) {
f.setX(5); // compile error, f is const
Foo &f2 = const_cast<Foo&>(f);
f2.setX(5); // compiles just fine
}
The useful part is that unintentional attempts to change the object will result in compiler errors, a determined programmer can easily circumvent these protections.
In a project I maintain, I see a lot of code like this for simple get/set methods
const int & MyClass::getFoo() { return m_foo; }
void MyClass::setFoo(const int & foo) { m_foo = foo; }
What is the point in doing that instead of the following?
int MyClass::getFoo() { return m_foo; } // Removed 'const' and '&'
void MyClass::setFoo(const int foo) { m_foo = foo; } // Removed '&'
Passing a reference to a primitive type should require the same (or more) effort as passing the type's value itself, right?
It's just a number after all...
Is this just some attempted micro-optimization or is there a true benefit?
The difference is that if you get that result into a reference yourself you can track the changes of the integer member variable in your own variable name without recalling the function.
const &int x = myObject.getFoo();
cout<<x<<endl;
//...
cout<<x<<endl;//x might have changed
It's probably not the best design choice, and it's very dangerous to return a reference (const or not), in case a variable that gets freed from scope is returned. So if you return a reference, be careful to be sure it is not a variable that goes out of scope.
There is a slight difference for the modifier too, but again probably not something that is worth doing or that was intended.
void test1(int x)
{
cout<<x<<endl;//prints 1
}
void test2(const int &x)
{
cout<<x<<endl;//prints 1 or something else possibly, another thread could have changed x
}
int main(int argc, char**argv)
{
int x = 1;
test1(x);
//...
test2(x);
return 0;
}
So the end result is that you obtain changes even after the parameters are passed.
To me, passing a const reference for primitives is a mistake. Either you need to modify the value, and in that case you pass a non-const reference, or you just need to access the value and in that case you pass a const.
Const references should only be used for complex classes, when copying objects could be a performance problem. In the case of primitives, unless you need to modify the value of the variable you shouldn't pass a reference. The reason is that references take more computation time than non-references, since with references, the program needs to look up in a table to find the address of the object. When this look-up time is shorter than the copying time, references are an improvement.
Generally, ints and addresses have the same byte length in low-level implementations. So the time of copying an int as a return value for a function is equivalent to the time of copying an address. But in the case where an int is returned, no look up is performed, therefore performance is increased.
The main difference between returning a value and returning a const reference is that you then can const_cast that reference and alter the value.
It's an example of bad design and an attempt to create a smart design where easy and concise design would be more than enough. Instead of just returning a value the author makes readers of code think what intention he might have had.
There is not much benefit. I have seen this in framework or macro generated getters and setters before. The macro code did not distinguish between primitive and non-POD types and just used const type& across the board for setters. I doubt that it is an efficiency issue or a genuine misunderstanding; chances are this is a consistency issue.
I think this type of code is written who have misunderstood the concept of references and use it for everything including primitive data types. I've also seen some code like this and can't see any benefit of doing this.
There is no point and benefit except
void MyClass::setFoo(const int foo)
void MyClass::setFoo(const int& foo)
as then you won't be able to reuse 'foo' variable inside 'setFoo' implementation. And I believe that 'int&' is just because Guy just get used to pass all things by const reference and there is nothing wrong with that.