Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 years ago.
I would be very grateful if someone explains me simply how can be recognised/understood, when the & operator should be used.
As reference stays:
& Address-of
and
The address of a variable can be obtained by preceding the name of a
variable with an ampersand sign (&), known as address-of operator. For
example:
foo = &myvar;
This would assign the address of variable myvar to foo; by preceding
the name of the variable myvar with the address-of operator (&), we
are no longer assigning the content of the variable itself to foo, but
its address.
But everything is too abstract for me.
For example here:
When we generate the integers in the main function,why is
if (!myDoc.setContent(&file, errorMsg, errorLine)) {
false?
//Here the code-lines->
QString errorMsg;
int errorLine;
QString errorMsg;
int errorLine;
if (!myDoc.setContent(&file, &errorMsg, &errorLine)) {
...
}
and how for example could be recognised here, that
QString maxString(const QString& s, int len)
should be used and not
QString maxString(const QString s, int len)
//Here stays the second example.
QString maxString(const QString& s, int len) {
if (s.size() < len) return s;
else return s.left(len)+"...";
}
void showTree(QTextStream& out, const QDomNode& node, const int intent) {
QString text;
if (node.nodeType() == QDomNode::ElementNode) {
...
}
} else if (node.nodeType() == QDomNode::TextNode) {
text = node.nodeValue().trimmed();
if (text.isEmpty()) return; // keine Ausgabe leerer Textknoten
text = "#text: "+maxString(text, 20);
}
...
}
&
used in declaration of a variable is different than when it is used in a code (I mean the part which runs).
In running code, it can be understood as "an address of". So
int i = 7;
std::cout << i; // output: 7
std::cout << &i; // output: 0x7fff2af8900 (or any other, mostly random, hex number)
The number output of &i
is an address, where the variable is stored. Adresses of a variables can be used in many ways (mostly in something called pointer arithmetics). For example, by definition of the language, an array in memory is stored sequentialy and continuously. Thus, int i[4];
defines array of 4
int
s, which are stored like boxes next to each other in memory. You can use i[1]
to touch second member of that array and i
(with no []
) holds the address to the first member.
Thus i == &i[0]
is always true for arrays.
However, in declaration, it is something called reference.
int value = 7;
int& ref = value; // with this, you can look at value using ref variable
value = 8;
std::cout << ref; // output: 8
EDIT:
When function with arguments is called, all of its arguments are copied and your function works with its own data. If you have function looks like bool check_validity(LargeData data)
which somehow processes tons of LargeData
and then returns true
if data is valid and false
otherwise. You are actually copying whole bunch of data into that function. And when after return from that function, the copy is lost. Now, copying is (time) expensive and if you don't need that copy, why would you copy that. If you pass that LargeData
pack using reference (as LargaData&
or better const LargeData&
to disable unwanted modification), only thing that actually copies, is some pointer of constant (most probably 8Bytes
) instead of whole data (which might be 10MBs or 500GB or even more).
So regarding your code QString maxString(const QString& s, int len)
is there just because you don't want to spend time copying s
input varibale if you only want to read its content.
Now, myDoc.setContent(&file, &errorMsg, &errorLine)
is probably some function which (using some rules) fills file
and returns true
if it was successful, and false otherwise, and if it was false, it also fills errorMsg
and errorLine
with some information why it failed. But, how do we define that function so that we can have that many output variables. Easy, we will pass address of a variable to that function and it will write to that address.
Those are two different uses of the &
operator:
The first use, in if (!myDoc.setContent(&file, errorMsg, errorLine))
, the &
operator returns the address of the file object. In this case, the & is needed because the setContent()
function has probably been declared like:
setContent(FileType * inputFile, ..., ...);
While declaring a function, the use of *
operator means that you will receive an address as a parameter. In this case, inputFile
expects a memory address, and by saying &file
you are passing the memory address of file
as parameter.
The second use of the &
operator is in function declaration. By using the & operator in a function declaration, you expect an object to be passed by reference. If you don't know it already, you should look up the difference between passing of parameters by value or by reference.
In a few words, passing a parameter by value means that you will pass a copy of the object, so the passed object will not be modified after the function call. Passing a value by reference means that the function will be able to modify the passed object.
Example:
void maxString(QString& s, int len) // s passed by reference
{
s = QString::ToUpper(s, len); // Just made that up
}
QString myString = "My string";
maxString(myString, myString.length());
// myString is now "MY STRING"
void maxString(QString s, int len) // s passed by value
{
s = QString::ToUpper(s, len); // Just made that up
}
QString myString = "My string";
maxString(myString, myString.length());
// myString is still "My string"
In C++ there are still other differences between passing by value or by reference.
Basically, passing by value means that you'll create a copy of the passed object, effectively calling the copy constructor for that object. This is in most cases not desired, since it uses CPU time for no reason. To overcome this, const ClassName &
is used. That means you'll be passing a constant reference to the object (i.e. no time wasted in copy constructor) and the function will not be able to modify the object.
You should look up the differences between passing by value/reference and the use of const.