I can't understand why it's writen CVector& and not CVector since the param is considered an object, not a pointer, since I read param.x and not param->x.
//This:
void swap(int *a, int *b)
{
int temp = *a;
*a=*b;
*b=temp;
}
//And this:
void swap(int &a, int &b)
{
int temp = a;
a=b;
b=temp;
}
Both of the functions above take reference of 2 variables (representation is different) but if the arguments passed in either if these functions are changed in the function then they will retain their value even after the function is over.
About you question why is there a CVector& param instead of CVector param, It is simple because if you don't take reference of the object of type CVector then the Copy constructor will be called again and again (recursively) as:
CVector func(CVector param);
will take argument like: //Calling function
func(obj);
this "func(obj);" call is equal to (CVector param = obj;) and this will call the copy constructor recursively.
both lhs and rhs are not modified, so why can't I define them as CVector, instead of CVector?, ie, why can't I pass them as value instead of reference? In this example I don't see any copy constructor.
Because passing by value makes copy of argument and destroys it at the end. Which can be quite costly.
When passing by reference you also do not have to worry if object is copyable at all.
Tatanan you can not see the copy constructor but it will be called implicitly when ever you pass any argument in overloaded operator if you define them as CVector. (see the link once which I gave you above.)
While If you use (const CVector& lhs ....) then this will also not change anything but because it is a reference that has been passed as an argument it will avoid calling the copy constructor.
Note: Each time you pass something as an argument in a function that take user-defined types; The copy constructor is called weather you explicitly define it or not.