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.
Related
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.”
This question already has answers here:
Literal initialization for const references
(3 answers)
Closed 2 years ago.
My understanding is that a const T& is internally implemented via a const T *const. If so, how is the below code valid (since we cannot take the address of 7)?
const int& i = 7;
Or does the compiler does some trick here? If so, what?
You cannot take the address of a literal like 7 but you can take the address of a temporary object whose value is 7.
Think of that line to be equivalent to
const int unnamed_temprary_variable = 7;
const int& i = unnamed_temprary_variable;
Or does the compiler does some trick here? If so, what?
The compiler does something analogous to the two lines I mentioned but it is not a trick. It is required by the language.
Searching for "extending the lifetime of temporaries" in SO resulted in a long list.
This question already has answers here:
Meaning of 'const' last in a function declaration of a class?
(12 answers)
Closed 6 years ago.
When coding a header file in C++ with method declarations, what's the difference between:
int getFoo() const;
const int getFoo();
const int getFoo() const;
First one, is for preventing this method changing any member variables of the object.
Second one, is for the return type (ie: constant integer)
Third one, is mix of both
Your first function operates on a const this pointer (that is; a const object that it can't change (or at least shouldn't)).
Your second function returns a constant integer - which is somewhat nonsensical since you can just assign it to a non-const variable and change it anyway. Besides, why does the function care if you change a POD type or not?
Your third function is just a combination of the first two. A function operating on a const object returning a const value.
This question already has answers here:
Why using the const keyword before and after method or function name?
(4 answers)
Closed 9 years ago.
I am working on a class project and my teacher has given us functions that we must write. Here is an example of one. I am wondering why there is a const at the beginning and the end. What do they do that they are needed on either end?
const Foo multiple(int value) const;
The first const applies to the return type of the member function.
The second const applies to the invisible this argument that is a pointer to the instance calling the Foo method.
First one is the type of the return value (const Foo), the second one means that it doesn't alter the class.
This question already has an answer here:
Why having const and non-const accessors?
(1 answer)
Closed 8 years ago.
So, I have to write two versions of the bracket operator for a class that I am writing.
Details:
The class has a private variable that is an array of strings.
The versions of operator[] differ in that one must be const, and the other not
I'm a little unsure how these two versions actually differ, and how when called, they will be able to be differentiated.
The one I currently have written
string& MyClass::operator[](unsigned int index);
simply returns the string at the index.
My question is, what is the point of having one const and one non-const? And how will they differ from each other?
EDIT:
Since I have to write these, will the code within each function be identical?
The correct overloaded versions are:
Access non const MyClass instance
std::string& MyClass::operator[](unsigned int index);
Access const or temp MyClass instance
const std::string& MyClass::operator[](unsigned int index) const;
The latter guarantees that access through a constant instance reference won't allow to modify the returned std::string reference, but to return a result though.
Implementation might need to consider that you could at least add new (default) string values to your container for currently unknown index values, and you'll need to decide how to handle unknown index values for const access (return empty string, throw exception, etc.).