1 What is the differences between void DoSomething(const Foo& foo) and void DoSomething(Foo foo)
? If we don't specify & then the instance of Foo
will be passed by value ( not reference ). It will be the same as having const + & in argument except no checking at compile-time. So, Why does having const + & become the best practice over the argument without & and const?
In C#, passing the object is "by reference" but seems like it's not in C++.
There are several differences, in order of importance:
- If the object
Foo
cannot be copied, you need to pass it by reference
- If the object
Foo
is a base class, you should get it by reference so that users can call your functions with derived classes
- The value of the actual object might change even though you hold a
const
reference to it
- Efficiency, copying user types might be expensive, but compilers may be smart enough to figure it out so...
2 The book that I'm reading said that Member functions pass the implicit parameter by reference..
Could anyone give me the sample of implicit parameter and by reference? I know that if we want to pass the object by reference, we need to use & (e.g. Foo(Person& p) ) but how come C++ pass the object by reference for implicit parameter? I read that implicit parameter in C++ is like Contructor(string str) : strMemberVariable(str) {} ...
By implicit parameter you should understand this
, that is the object itself. It is effectively passed by reference since you can modify its state in the member function.
Following Konrad
's remark: note that this
itself is not passed by reference, this
is a reference (pointer) to the object, but is passed by value. You can't change the memory address of your object as you wish ;)
3 Is the array the only that pass by reference in C++?
They aren't. You will see changes to the elements of the array, but the array (structure) will not change.
Following FredOverflow
's remark, an illustration:
void fun(int* p, size_t size);
int main(int argc, char* argv[])
{
int array[15];
fun(array, 15);
}
We don't know what fun
does, it will probably change some elements of array
, but whatever its action, array
will remain an Array of 15 integers: the content changes, the structure does not.
As a result, to change array
we need another declaration:
void changer(int*& array, size_t& size);
This way we can change both the content and the structure (and pass back the new size too). And of course we can only call this function with an array that was dynamically allocated.
4 Why can't I use Foo fInstance in Foo class?
Because that's infinite recursion. Think about it from a compiler point of view, and try to guess the size of Foo
. The size of Foo
is the sum of the sizes of its attributes, plus possibly some padding and type information. Also, an object size is at least 1
so that it can be addressed. So, if Foo
has a Foo
, what's its size :) ?
The usual solution is to use a smart pointer:
class Foo
{
public:
private:
std::unique_ptr<Foo> mInstance;
};
Because the size of a pointer does not depend on the size of the object pointed to, so there is not recursion going on here :)