Qt - Is this pass by reference? - c++

If we write the following in Qtas an argument to a function: QString &tableName
Does that mean we are passing by reference?
Thanks.

Strictly speaking, that is a function parameter, not a function argument. The parameter is the variable declared inside the function's parameter list; the argument is the value passed to the function by the calling function. So parameter QString &tableName is passed by reference. But as a function argument, &tableName would mean "the address of tableName".
Updated: As requested, here is a code sample to clarify the distinction:
void f (double y) ;
f (99.0) ;
double y is a parameter declaration; it resembles a variable declaration. y is a function parameter.
99.0 is a function argument; it is an expression, that must be convertible to type double.

Yes, this is pass-by-reference in C++. You could also write QString const & tableName, if you don't want to have the very possibility of accidentally changing tableName.

Yes. Tip: make it const if you don't want it to change.

Note that, like most non-trivial Qt basic types, QString is a lightweight container object that implements "copy on write" semantics. So the only reason to pass one by reference is if your function wants to modify the caller's copy, and there is never any reason to pass one by const reference (unless you do not know much about Qt).

Related

Why my class keeps reseting and doesnt keep my changes [duplicate]

A simple question for which I couldn't find the answer here.
What I understand is that while passing an argument to a function during call, e.g.
void myFunction(type myVariable)
{
}
void main()
{
myFunction(myVariable);
}
For simple datatypes like int, float, etc. the function is called by value.
But if myVariable is an array, only the starting address is passed (even though our function is a call by value function).
If myVariable is an object, also only the address of the object is passed rather than creating a copy and passing it.
So back to the question. Does C++ pass a object by reference or value?
Arguments are passed by value, unless the function signature specifies otherwise:
in void foo(type arg), arg is passed by value regardless of whether type is a simple type, a pointer type or a class type,
in void foo(type& arg), arg is passed by reference.
In case of arrays, the value that is passed is a pointer to the first element of the array. If you know the size of the array at compile time, you can pass an array by reference as well: void foo(type (&arg)[10]).
C++ always gives you the choice: All types T (except arrays, see below) can be passed by value by making the parameter type T, and passed by reference by making the parameter type T &, reference-to-T.
When the parameter type is not explicitly annotated to be a reference (type &myVariable), it is always passed by value regardless of the specific type. For user-defined types too (that's what the copy constructor is for). Also for pointers, even though copying a pointer does not copy what's pointed at.
Arrays are a bit more complicated. Arrays cannot be passed by value, parameter types like int arr[] are really just different syntax for int *arr. It's not the act of passing to a function which produces a pointer from an array, virtually every possible operation (excluding only a few ones like sizeof) does that. One can pass a reference-to-an-array, but this explicitly annotated as reference: int (&myArray)[100] (note the ampersand).
C++ makes both pass by value and pass by reference paradigms possible.
You can find two example usages below.
http://www.learncpp.com/cpp-tutorial/72-passing-arguments-by-value/
http://www.learncpp.com/cpp-tutorial/73-passing-arguments-by-reference/
Arrays are special constructs, when you pass an array as parameter, a pointer to the address of the first element is passed as value with the type of element in the array.
When you pass a pointer as parameter, you actually implement the pass by reference paradigm yourself, as in C. Because when you modify the data in the specified address, you exactly modify the object in the caller function.
In C++, types declared as a class, struct, or union are considered "of class type". These are passed by value or you can say a copy using copy constructor is passed to the functions. This is pretty evident when we implement binary trees wherein you almost always have a Node * type of param in the recursive function acting on the binary tree. This is so as to facilitate modification of that node. If the node were to be passed as is (i.e not being a pointer type), the modifications to the nodes would have been to the local copy. Even in the case of vectors, while passing a copy of vectors is passed to the functions, to avoid which we use a reference &.
C++ passes arguments that are no pointers (int*) or references (int&) by value. You cannot modify the var of the calling block in the called function. Arrays are pointers.

is correct to change argument value inside function

In this code I change iType variable which is a function parameter. It works fine, but is it correct?
void ImgCoreQCV::IPThreshold( double dThresh, double dMaxval, int iType, bool bTreshOtsu ) {
if(bTreshOtsu)
iType |= THRESH_OTSU;
if(undoVector.back().channels()!=1)
cvtColor(undoVector.back(),CurImg,CV_BGR2GRAY);
threshold(CurImg,CurImg,dThresh,dMaxval,iType);
}
I mean that I did not create a new variable and has changed it:
int iThreshType = iType;
if(bTreshOtsu)
iThreshType = iType | THRESH_OTSU;
threshold(CurImg,CurImg,dThresh,dMaxval,iThreshType);
It is correct in this particular case, and it has no side effect since the argument here is a copy of the actual parameter passed.
But it might make a trouble in general case, if you unintentially change parameter passed by reference.
Also modifying parameters usually make the code worse readable. And might require more time for understanding what is really happening in the function.
So, generally I wouldn't recommend modifying parameters. Leave this optimization to the compiler.
As long you don't have by reference parameters, changing the value won't have any effect outside of your function.
It's fine to do so and you don't need a extra variable.
You can create a temporary variable inline of the lowest function call like this:
threshold(CurImg,CurImg,dThresh,dMaxval, bTreshOtsu ? iType|THRESH_OTSU : iType);
There are a couple of things that you should be clear on regarding function parameters:
void IPThreshold( double dThresh, double dMaxval, int iType, bool bTreshOtsu );
The above function will pass copies of each of the parameter values to the function body. When invoked with a local variable then the value of the local variable is unchanged after you modify it in the function.
void IPThreshold( double& dThresh, double& dMaxval, int& iType, bool bTreshOtsu );
Above the function will use non-const references which means that you can modify the value of the referenced parameter within the function. If you call this version with a local variable and you modify the parameter then the local variable will be modified after the call returns.
You also ask if this is okay... well I personally attempt not to use parameters for this if I can avoid it as I think that return values are generally clearer. However there is nothing wrong with it. The only caveat I would say is that you should be consistent with the meaning of how you pass your parameters.

Does C++ pass objects by value or reference?

A simple question for which I couldn't find the answer here.
What I understand is that while passing an argument to a function during call, e.g.
void myFunction(type myVariable)
{
}
void main()
{
myFunction(myVariable);
}
For simple datatypes like int, float, etc. the function is called by value.
But if myVariable is an array, only the starting address is passed (even though our function is a call by value function).
If myVariable is an object, also only the address of the object is passed rather than creating a copy and passing it.
So back to the question. Does C++ pass a object by reference or value?
Arguments are passed by value, unless the function signature specifies otherwise:
in void foo(type arg), arg is passed by value regardless of whether type is a simple type, a pointer type or a class type,
in void foo(type& arg), arg is passed by reference.
In case of arrays, the value that is passed is a pointer to the first element of the array. If you know the size of the array at compile time, you can pass an array by reference as well: void foo(type (&arg)[10]).
C++ always gives you the choice: All types T (except arrays, see below) can be passed by value by making the parameter type T, and passed by reference by making the parameter type T &, reference-to-T.
When the parameter type is not explicitly annotated to be a reference (type &myVariable), it is always passed by value regardless of the specific type. For user-defined types too (that's what the copy constructor is for). Also for pointers, even though copying a pointer does not copy what's pointed at.
Arrays are a bit more complicated. Arrays cannot be passed by value, parameter types like int arr[] are really just different syntax for int *arr. It's not the act of passing to a function which produces a pointer from an array, virtually every possible operation (excluding only a few ones like sizeof) does that. One can pass a reference-to-an-array, but this explicitly annotated as reference: int (&myArray)[100] (note the ampersand).
C++ makes both pass by value and pass by reference paradigms possible.
You can find two example usages below.
http://www.learncpp.com/cpp-tutorial/72-passing-arguments-by-value/
http://www.learncpp.com/cpp-tutorial/73-passing-arguments-by-reference/
Arrays are special constructs, when you pass an array as parameter, a pointer to the address of the first element is passed as value with the type of element in the array.
When you pass a pointer as parameter, you actually implement the pass by reference paradigm yourself, as in C. Because when you modify the data in the specified address, you exactly modify the object in the caller function.
In C++, types declared as a class, struct, or union are considered "of class type". These are passed by value or you can say a copy using copy constructor is passed to the functions. This is pretty evident when we implement binary trees wherein you almost always have a Node * type of param in the recursive function acting on the binary tree. This is so as to facilitate modification of that node. If the node were to be passed as is (i.e not being a pointer type), the modifications to the nodes would have been to the local copy. Even in the case of vectors, while passing a copy of vectors is passed to the functions, to avoid which we use a reference &.
C++ passes arguments that are no pointers (int*) or references (int&) by value. You cannot modify the var of the calling block in the called function. Arrays are pointers.

Under what scenarios would you declare a non-reference, non-pointer type function parameter const?

I have the following function declaration:
void fn(int);
This function has a single integral type parameter. Now, I could call this function by passing a non const or a const integral object. In either case, this function is going to copy the object to its local int parameter. Therefore, any modifications to this parameter is going to be local to the function and is not going to affect the actual arguments of the caller in any way. Now my question is under which scenario will I declare this single int parameter to be of const type? I don't see a need to declare this function as follows.
void fn(const int);
This is because the arguments are going to be anyway passed by value and the function can in no way modify the arguments in either case. I understand that by declaring a parameter constant the function cannot modify it inside its body. However, there is no downside here even if the function modifies since the parameter is local to the function.
You're right that to the caller there is no difference -- it only matters inside the function. I prefer to add the const whenever I can. As I'm writing the function, I'm thinking "I want this parameter but have no intention of modifying it (even just locally)" and the compiler will keep me honest.
Also, in some cases the compiler may be able to do more optimizations if it knows the variable is const (as in loop bounds).
Just because it's allowed, doesn't mean there's a point to it.
I wouldn't be surprised if this could cause overloading to behave slightly differently, but I think you're basically right - there's no good outside-the-function reason to do it.
One possible problem is confusing readers who might think you intended a reference instead, but forgot the "&".
Sometimes templates are written in a general way, and end up doing things like that. With function template parameter deduction, though, that const tends to get thrown away.
this is effectively a const argument. It is a pointer, but it's immutable in the sense of your example. (Of course, this is a keyword, not a variable, and unary & doesn't work with it.) If you want an argument to behave like that, declare it const.
From the C++ Spec: http://www.kuzbass.ru:8086/docs/isocpp/over.html
Parameter declarations that differ
only in the presence or absence of
const and/or volatile are equivalent.
That is, the const and volatile
type-specifiers for each parameter
type are ignored when determining
which function is being declared,
defined, or called.
Example:
typedef const int cInt;
int f (int);
int f (const int); // redeclaration of f(int)
int f (int) { ... } // definition of f(int)
int f (cInt) { ... } // error: redefinition of f(int)
A favorite interview question in C++ interview is what is the difference between passing by values, passing by pointer and passing by reference.
In this case we are passing by value and that too int and hence it will not matter. But I am not sure about the user created classes. In that case when the compiler see the object is passed by const value it may decide to pass it by the const reference. Nowdays compilers are intelligent and I don't see why they can not do it.

Regarding address operator C/C++

What does address operator mean.
say in the method below.
what should be passed in the method as parameter value of integer or the address of an integer variable.
void func1(int&)// method declaration
void func1(int& inNumber)//method definition
{
//some code
}
That’s not the address operator – it’s the reference type character. This means that for any type T, T& is a reference to T. It’s an unlucky coincidence that this happens to be the same character as the address operator.
You can pass normal objects to this method. No need to take any further action. Read up on references in your favourite C++ book.
There is no address-of operator in your code - the ampersand is being used to declare a reference. Which C++ text book are you using that does not cover this?
In this case the function takes a reference to an int which is denoted by the int &inNumber.
The function is called as if you were calling it with the value:
int x = 2;
func1(x);
From the perspective of the caller, this looks exactly the same as a pass by value function, though in the case of the reference the function may indeed change the value of x.
That's not an address operator. In a declaration, the & means it's a reference.
You can think of references as pointers that you don't have to dereference.* You can just say inNumber = 5; (instead of *inNumber = 5;) and the effect will be visible outside the function.
* Note: References are not just "pointers that you don't have to dereference". It just helps to think of them in that way, sometimes.
its called as reference in c++
http://en.wikipedia.org/wiki/Reference_(C%2B%2B)