[SOLVED] When Ampersand(&) is needed?
-
In addition, you should keep in mind that C++ uses the & as reference operator to retrieve the address of an object in memory as well.
@
QObject object;
QObject* objectPointer = &object;
@So the meaning of & is a bit different dependig whether used with types or variables.
-
[quote author="octal" date="1313849117"]
lvalue
[/quote]can you explain to me this term?
[quote]
the literal string "Hello" (which is of type const char[ 6 ]) will result in a temporary (rvalue)
[/quote]Are you sure that hello is a const char[6]???
@const char[] hello = "hello";
qDebug() << hello[6];@This doesn't give an ouput.I am almost sure that in c++ arrays count from zero so 5 is 4.
[quote author="Lukas Geyer" date="1313852985"]
So the meaning of & is a bit different dependig whether used with types or variables.[/quote]@//it is used in variables
QObject obj;
QWidget wid = &obj;//it is used in types
something(const QString &string);@
correct?
Moreover,
@void startJob(Job &work){
.....
delete &work;}void doJob(){
Job *doing = new Job;
startJob(doing);}
//no compiler error
@In this situation why the pointer is valid?
Is this because of the usage of the ampersand?@void startJob(Job &work)@
In conclusion,after a little search,i found a good article and i understand the reference mechanism.
So the reference is being used in order to avoid copying(making slower) our application.
Is there any reason,for which i should use the reference mech in my functions?
thank you for your help :)
-
bq. can you explain to me this term?
an lvalue refers to an expression that has a name and persists in memory, as opposite to rvalue which refers to a temporary.
bq.
Are you sure that hello is a const char6???
1
2
const char[] hello = "hello";
qDebug() << hello[6];
This doesn’t give an ouput.I am almost sure that in c++ arrays count from zero so 5 is 4.Yes in fact, this is « const char[ 5 ] ». But I meant the type of "hello" is « const char[ 5 ] », my bad.
EDIT: erf, I was right, you have a final '\0', so this is const char[ 6 ].
@
//it is used in variables
QObject obj;
QWidget wid = &obj;
@I don't understand what you're trying to achieve here.
bq. Is there any reason,for which i should use the reference mech in my functions?
anytime you don't need useless copies.
Anyway, I think you need to take a C++ course before going on with Qt. You can look at the wiki for some good books :)
-
[quote author="octal" date="1313867563"]bq. can you explain to me this term?
Yes in fact, this is « const char[ 5 ] ». But I meant the type of "hello" is « const char[ 5 ] »
[/quote]I can produce an output with const char [5] only with 4 or less.
[quote]
@
//it is used in variables
QObject obj;
QWidget wid = &obj;
@I don't understand what you're trying to achieve here.
[/quote]I am trying to tell you if understand correctly when the reference is used for memory and when it doesn't.
-
@void something(QString &string);@ This is call by reference. Like its said before, use of & is different[Than the usuall meaning "address of", am sure that makes all the confusions ;)]. Its just telling compiler, okay dont copy, just save time and memory.
Now, If you want to save the copying time, memory, and also don't want to change the original value, just put 'const'
@void something(const QString &string);@And when you 'call by value' , @void something(QString string);
void something(const QString string);@ ,Still, Qt is smarter ;), cow [copy on write] comes to action,like its said before.The errors you got , probably because of something in the declaration part, i suppose.
..............................................................................Interestingly, foreach keyword has something to tell. :) It is a macro and is implemented using the preprocessor. You should go through the "docs":http://doc.qt.nokia.com/latest/containers.html#the-foreach-keyword.
And i think,here again same laws as above.. [ copy / dont copy ]
@QStringList list = populateStringList();
foreach(QString &item,list){ //dont copy, direct access
if(item=="hello"){
......}
//EDIT:
foreach(const QString &item,list){ //dont copy, no change allowed!
if(item=="hello"){
......}
//EDIT : 2
foreach(QString item,list){ // copy!
if(item=="hello"){
......}
@EDIT 2:
NOTE : Its clear in the document
Qt automatically takes a copy of the container when it enters a foreach loop. If you modify the container as you are iterating, that won't affect the loop. (If you do not modify the container, the copy still takes place, but thanks to implicit sharing copying a container is very fast.)Since foreach creates a copy of the container, using a non-const reference for the variable does not allow you to modify the original container. It only affects the copy, which is probably not what you want.
-
[quote author="Giorgos Tsiapaliwkas" date="1313865773"]
[quote]
the literal string "Hello" (which is of type const char[ 6 ]) will result in a temporary (rvalue)
[/quote]Are you sure that hello is a const char[6]???
@const char[] hello = "hello";
qDebug() << hello[6];@This doesn't give an ouput.I am almost sure that in c++ arrays count from zero so 5 is 4.
[/quote]There is a difference between char[] as a type and char[] as an index access.
- const char[] hello = "hello" reserves a consecutive block of memory which stores the characters of the word "hello" at position 0 - 4 and a trailing '\0' at position 5 which terminates strings in C++.
- hello[ 6 ] returns the character stored at position 6 in this consecutive block of memory. Obviously there is none, because the positions range from 0 to 5. Thus you get no output.
[quote author="Giorgos Tsiapaliwkas" date="1313865773"][quote author="Lukas Geyer" date="1313852985"]
So the meaning of & is a bit different dependig whether used with types or variables.[/quote]@//it is used in variables
QObject obj;
QWidget wid = &obj;//it is used in types
something(const QString &string);@
correct?[/quote]
The idea is right, the code is wrong. The reference operator returns the address of an object, not an object. This address has to be stored in a variable of type "pointer to object", not "object". Take another look at the code I've posted.
In addition, the pointer has to be of the same type as the object. Otherwise you will have to do an explicit type conversion using a cast (or this is done for you implicitly, as for example in inheritance hierarchies).
[quote author="Giorgos Tsiapaliwkas" date="1313865773"]
Moreover,
@void startJob(Job &work){
.....
delete &work;}void doJob(){
Job *doing = new Job;
startJob(doing);}
//no compiler error
@In this situation why the pointer is valid?
Is this because of the usage of the ampersand?[/quote]I don't think this code compiles.
startJob(Job& work) expects an parameter of type Job, whereas the parameter you pass doing is of type pointer to Job (Job*). That's two different things, two different types.
-
[quote author="Lukas Geyer" date="1313852985"]
I don't think this code compiles.
[/quote]Yes you have right.The code that compiles is this one,
@void startJob(Job &work){
.....
delete &work;}void doJob(){
Job *doing = new Job;
startJob(*doing);}@thanks you all of you for help and for your time.
I will mark the thread as solved.
thanks
-
Sorry for that comment, Giorgos, but reading this code make me nervous:
@
void startJob(Job &work)
{
.....
delete &work;
}
@A reference means you get a reference to an object, but that could be loacted on the stack, the heap or even anywhere else (a const ref also in code segment). If you want to delete some memory by it, I would prefer using pointers as parameters´.
I would prefer here:
@
void startJob(Job* work)
{
.....
delete work;
}
@ -
[quote author="Gerolf" date="1314004264"]Sorry for that comment, Giorgos, but reading this code make me nervous:[/quote]
no problem.Comments are more than welcome :)
@
void startJob(Job &work)
{
.....
delete &work;
}
@this code is not writen by me.Its just a code that i came across.
[quote]I would prefer here:
@
void startJob(Job* work)
{
.....
delete work;
}
@[/quote]So do I.:)
thank you for your comment
-
Welcome.
The point why I wrote that comment is, that a pointer can be invalid (which is typically 0), a reference should never be invalid. It should always reference a valid object.