This question already has answers here:
What are the differences between a pointer variable and a reference variable?
(44 answers)
Address-of operator (&) vs reference operator(&)
(3 answers)
Use of the & operator in C++ function signatures
(9 answers)
Meaning of references, address-of, dereference and pointer
(4 answers)
Closed 1 year ago.
I'm back to doing some C++ work after 30 years or so (I was always more a C and later Objective-C person and haven't programmed in any C-like language for quite a while). And while I get things working, there is something in C++ that I cannot make sense of in my (C?) thinking. It is about this (simplified):
string line;
getline( line);
The getline function's argument is of type string&, i.e. declaration:
bool getline( string &str);
Now it is clear that the line object needs to pass 'by reference' to the getline() function. After all, we want to fill our line object and not some throwaway copy. So, my intuition says I need to say:
getline( &line);
In C I would expect something like:
struct line; // contains the array, kind of C++ without member functions
getline( &line);
and the function as
getline( struct line*);
The question is: how does an seemingly by-value call of getline( line) turn into the actual by-reference passing of the object? What happens in the background?
My guess is that a definition like
string line;
actually creates a pointer (line) of a different type than the * type.
I think what confuses me is that the call description string & (with &) is different from the definition string line; (without &). In C no such thing happens.
Can someone provide a good explanation to make me understand it in full?
When a function parameter is declared as a reference, as is string &str in bool getline(string &str), and the function is called, as with getline(line), the compiler passes the address of the argument to the function. That is, in the register or other location where an argument is passed to the function, the compiler puts the address of line instead of the value. (Technically, the compiler could use something other than the memory address, but it will be a functional equivalent.)
Effectively, declaring a parameter as a reference means “Automatically take the address of an argument and pass that, and, wherever the parameter is used in the function, automatically use the object that the passed address points to, as if *x had been used instead of x.”
Related
What does '&' mean in C++?
As within the function
void Read_wav::read_wav(const string &filename)
{
}
And what is its equivalent in C?
If I want to transform the above C++ function into a C function, how would I do it?
In that context, the & makes the variable a reference.
Usually, when you pass an variable to a function, the variable is copied and the function works on the copy. When the function returns, your original variable is unchanged. When you pass a reference, no copy is made and changes made by the function show up even after the function returns.
C doesn't have references, but a C++ reference is functionally the same as a pointer in C. Really the only difference is that pointers have to be dereferenced when you use them:
*filename = "file.wav";
But references can be used as though they were the original variable:
filename = "file.wav";
Ostensibly, references are supposed to never be null, although it's not impossible for that to happen.
The equivalent C function would be:
void read_wav(const char* filename)
{
}
This is because C doesn't have string. Usual practice in C is to send a pointer to an array of characters when you need a string. As in C++, if you type a string constant
read_wav("file.wav");
The type is const char*.
It means that the variable is a reference. There is no direct equivalent in C. You can think of it as a pointer that is automatically dereferenced when used, and can never be NULL, maybe.
The typical way to represent a string in C is by a char pointer, so the function would likely look like this:
void read_wav(struct Read_wav* instance, const char *filename)
{
}
Note: the first argument here simulates the implicit this object reference you would have in C++, since this looks like a member method.
The ampersand is used in two different meanings in C++: obtaining an address of something (e.g. of a variable or a function) and specifying a variable or function parameter to be a reference to an entity defined somewhere else. In your example, the latter meaning is in use.
C does not have strictly speaking anything like the reference but pointers (or pointers to pointers) have been user for ages for similar things.
See e.g. http://www.cprogramming.com/tutorial/references.html, What are the differences between a pointer variable and a reference variable in C++? or http://en.wikipedia.org/wiki/Reference_%28C%2B%2B%29 for more information about references in C++.
In C, you would write it this way:
void read_wav(struct Read_wav* , const char * pSzFileName)
{
}
std::string is the C++ way of dealing with array of const char.
& is a C++ reference. It behaves just as if you were handling the pointer behind ( its is mainly a syntactic sugar, thought it prompts the contract that the pointer behind should not be null).
In this particular case, std::string has a c_str method which returns a const char *. You can make a parallel C version and then have your C++ do something like:
void Read_wav::read_wav(const string &filename)
{
do_read_wav(internal_read_wav, filename.c_str());
}
where do_read_wav is your C routine and internal_read_wav is a pointer to a C-style struct.
void do_read_wav(struct Read_wav rw, const char * filename)
Now, if you are storing information in the class, you need to make a C struct [all of the fields must be POD, etc]
References are aliases, they are very similar to pointers.
std::string is an array of char with an explicit length (that is, there can be null characters embedded within).
There is a C-library to emulate std::string (that is, provide an encapsulated interface) called bstring for Better String Library. It relieves you from the tedium of having to deal with two distinct variables (array and length).
You cannot use classes in C, but you can emulate them with forwarded struct (to impose encapsulation) and class methods simply become regular functions with an explicit parameter.
Altogether, this leads to the following transformation:
void Read_wav::read_wav(const string &filename);
void read_wav(struct Read_wav* this, struct bstring const* filename);
Which (apart from the struct noise) is very similar to what you had before :)
& means that variable is passed via reference. So, inside your function you will have not a local copy of variable, but the original variable itself. All the changes to the variable inside the function will influence the original passed variable.
You might want to check out Binky Pointer fun, it's a video that illustrates what Pointers and References are.
In this case, string &filename means the function will receive a reference (a memory address) as a parameter, instead of receiving it as a copy.
The advantage of this method is that your function will not allocate more space on the stack to save the data contained in filename.
It's a reference, as others have said.
In C, you'd probably write the function as something like
void read_wav(struct Read_wav* rw, const char* filename)
{
}
&filename means this is a reference to filename.
This question already has answers here:
What's the difference between passing by reference vs. passing by value?
(18 answers)
Closed 6 years ago.
I am a C++ newbie and I am working on a program that simulates a phonebook. Now, for the insert operation, function is defined as follows:
void PhoneBook::insert(const string& name, const string& number)
But it still works and inserts the contact as well if I remove the reference symbols. So, I am a little confused here, why do I need them?
void PhoneBook::insert(const string name, const string number)
void PhoneBook::insert(const string name, const string number)
Here you are constructing new strings with copy of all data. This is heavy operation.
void PhoneBook::insert(const string& name, const string& number)
Here you are passing reference to string (address of string), size of which is usually 4 or 8 bytes, based on platform, which is very light operation.
Also, when you pass reference, you are allowed to interact with object, which you are passed to function.
Rule of thumb - always pass by const reference, if variable is bigger than 8 bytes and you dont require explicit copy of object.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
const CFoo &bar() const
Which is the meaning of this line?
virtual void Encode (KDataStream & stream) const;
What´s the meaning of const at the end in C++?
Which is the meaning of this line?
virtual void Encode (KDataStream & stream) const;
It's a statement that declares a function.
virtual means it's a member function that can be overridden by a function of the same name and compatible parameter and return types declared in a class derived from this one. The correct version will be chosen (at run-time, if necessary) according to the type of the object it's invoked on.
void means it doesn't return anything.
Encode is the name of the function.
( marks the start of the parameter list.
KDataStream is the type of the first parameter.
& means the parameter is passed by reference.
stream is the name given to the parameter; it serves as documentation, but can be left out of the declaration without changing the meaning.
) marks the end of the parameter list.
const means that it's a member function that can't modify non-static, non-mutable data members of the object it's invoked on. It also allows it to be invoked on objects that are declared const.
; marks the end of the statement.
It means -- pass by reference.
The 'const' at the end of the method says that the method implementation will not change the values of any member variables. So, by seeing this in the class interface itself (without having to know the implementation), the clients of the object can know about this behaviour.
Read up on pointers, if you want to code in c++ you will need to know how these work:
http://www.cplusplus.com/doc/tutorial/pointers/
& means you are passing in the memory address of stream rather the value of stream
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
C++ functions: ampersand vs asterisk
What are the distinctions between the various symbols (*,&, etc) combined with parameters?
I am wondering the difference between the address operator & and the deference operator * in a C++ function call. For example take the following function
void foo (std::string& param)
{
param = "Bar.";
std::cout << param.size();
}
and let's call it in our main() function like so...
int main()
{
std::string test;
foo(test); //Why not foo(&test)?
std::cout << test; //Prints out the value "Bar."
}
First off, why does the & operator allow me to assign a value as if it were a pointer (assigning it a value that survives the RAII and scope of the function foo() when it's not a pointer) as it is able to be printed out in my main() function even though it's not static? I am assuming it is not a pointer because I am able to access the size() method by using the . operator instead of the -> which is used for pointers.
Secondly, what would be the difference between using the & operator in a function parameter vs. using the * operator? Is it even different than just a plain variable like std::string param? It appears to be called like that (foo(test) instead of foo(&test)).
& function parameter specifically signifies that this parameter is being passed-in by reference (traditionally compilers implement this as a pointer) which is why you see the effect of this assignment in your main().
static would have nothing to do with that.
The difference in declaring a parameter to a function using & and * is that the second one allows a nullptr (or a non-existent or just a plain invalid address) to be passed-in while the & guarantees that there's a real object being referenced by this function's argument. Other than that both provide similar functionality of allowing an original object to be changed via it's reference.
test on it's own (without &) would pass a copy to the string to the function, whilst the & means it will pass a reference.
FYI: When you don't need a reference, best-practise dictates passing all objects as const references.
I'm currently reading through Accelerated C++ and I realized I don't really understand how & works in function signatures.
int* ptr=#
means that ptr now holds the address to num, but what does that mean?
void DoSomething(string& str)
from what I understand that is a pass by reference of a variable (which means passing the address) but when I do
void DoSomething(string& str)
{
string copy=str;
}
what it creates is a copy of str. What I thought it would do is raise an error since I'm trying to assign a pointer to a variable.
What is happening here? And what is the meaning of using * and & in function calls?
A reference is not a pointer, they're different although they serve similar purpose.
You can think of a reference as an alias to another variable, i.e. the second variable having the same address. It doesn't contain address itself, it just references the same portion of memory as the variable it's initialized from.
So
string s = "Hello, wordl";
string* p = &s; // Here you get an address of s
string& r = s; // Here, r is a reference to s
s = "Hello, world"; // corrected
assert( s == *p ); // this should be familiar to you, dereferencing a pointer
assert( s == r ); // this will always be true, they are twins, or the same thing rather
string copy1 = *p; // this is to make a copy using a pointer
string copy = r; // this is what you saw, hope now you understand it better.
The & character in C++ is dual purpose. It can mean (at least)
Take the address of a value
Declare a reference to a type
The use you're referring to in the function signature is an instance of #2. The parameter string& str is a reference to a string instance. This is not just limited to function signatures, it can occur in method bodies as well.
void Example() {
string s1 = "example";
string& s2 = s1; // s2 is now a reference to s1
}
I would recommend checking out the C++ FAQ entry on references as it's a good introduction to them.
https://isocpp.org/wiki/faq/references
You shouldn't know anything about pointers until you get to chapter 10 of Accelerated C++ !
A reference creates another name, an alias, for something that exists elsewhere. That's it. There are no hidden pointers or addresses involved. Don't look behind the curtain!
Think of a guy named Robert
guy Robert;
Sometimes you may want to call him Bob
guy& Bob = Robert;
Now Bob and Robert both refer to the same guy. You don't get his address (or phone number), just another name for the same thing.
In your function
void DoSomething(string& str)
{
string copy=str;
}
it works exactly the same, str is another name for some string that exists somewhere else.
Don't bother with how that happens, just think of a reference as a name for some object.
The compiler has to figure out how to connect the names, you don't have to.
In the case of assigning variables (ie, int* ptr = &value), using the ampersand will return the address of your variable (in this case, address of value).
In function parameters, using the ampersand means you're passing access, or reference, to the same physical area in memory of the variable (if you don't use it, a copy is sent instead). If you use an asterisk as part of the parameter, you're specifying that you're passing a variable pointer, which will achieve almost the same thing. The difference here is that with an ampersand you'll have direct access to the variable via the name, but if you pass a pointer, you'll have to deference that pointer to get and manipulate the actual value:
void increase1(int &value) {
value++;
}
void increase2(int *value) {
(*value)++;
}
void increase3(int value) {
value++;
}
Note that increase3 does nothing to the original value you pass it because only a copy is sent:
int main() {
int number = 5;
increase1(number);
increase2(&number);
increase3(number);
return 0;
}
The value of number at the end of the 3 function calls is 7, not 8.
It's a reference which allows the function to modify the passed string, unlike a normal string parameter where modification would not affect the string passed to the function.
You will often see a parameter of type const string& which is done for performance purposes as a reference internally doesn't create a copy of the string.
int* ptr=#
1st case: Since ptr is a memory and it stores the address of a variable. The & operator returns the address of num in memory.
void DoSomething(string& str)
2nd case: The ampersand operator is used to show that the variable is being passed by reference and can be changed by the function.
So Basically the & operator has 2 functions depending on the context.
While pass by reference may be implemented by the compiler by passing the address as a pointer, semantically it has nothing to do with addresses or pointers. in simple terms it is merely an alias for a variable.
C++ has a lot of cases where syntax is reused in different contexts with different semantics and this is one of those cases.
In the case of:
int* ptr=#
you are declaring a variable named ptr with a type of an int * (int pointer), and setting its value to the "address of the variable num" (&num). The "addressof" operator (&) returns a pointer.
In the case of:
void DoSomething(string& str)
you are declaring the first parameter of the DoSomething() method to be of type "reference to string". Effectively, this is the C++ way of defining "pass-by-reference".
Note that while the & operator operates similarly in these cases, it's not acting in the same way. Specifically, when used as an operator, you're telling the compiler to take the address of the variable specified; when used in a method signature, you're telling the compiler that the argument is a reference. And note as well, that the "argument as a reference" bit is different from having an argument that is a pointer; the reference argument (&) gets dereferenced automatically, and there's never any exposure to the method as to where the underlying data is stored; with a pointer argument, you're still passing by reference, but you're exposing to the method where the variable is stored, and potentially exposing problems if the method fails to do a dereference (which happens more often than you might think).
You're inexplicitly copy-constructing copy from str. Yes, str is a reference, but that doesn't mean you can't construct another object from it. In c++, the & operator means one of 3 things -
When you're defining a normal reference variable, you create an alias for an object.
When you use it in a function paramater, it is passed by reference - you are also making an alias of an object, as apposed to a copy. You don't notice any difference in this case, because it basically is the object you passed to it. It does make a difference when the objects you pass contain pointers etc.
The last (and mostly irrelevent to your case) meaning of & is the bitwise AND.
Another way to think about a reference (albeit slightly incorrect) is syntactic sugar for a dereferenced pointer.