mirror of
https://github.com/adambard/learnxinyminutes-docs.git
synced 2024-12-23 09:41:36 +00:00
A little more about C++ references
This commit is contained in:
parent
a6af51e42f
commit
1d1def16a5
@ -4,6 +4,7 @@ filename: learncpp.cpp
|
|||||||
contributors:
|
contributors:
|
||||||
- ["Steven Basart", "http://github.com/xksteven"]
|
- ["Steven Basart", "http://github.com/xksteven"]
|
||||||
- ["Matt Kline", "https://github.com/mrkline"]
|
- ["Matt Kline", "https://github.com/mrkline"]
|
||||||
|
- ["Geoff Liu", "http://geoffliu.me"]
|
||||||
lang: en
|
lang: en
|
||||||
---
|
---
|
||||||
|
|
||||||
@ -248,6 +249,56 @@ const string& barRef = bar; // Create a const reference to bar.
|
|||||||
// Like C, const values (and pointers and references) cannot be modified.
|
// Like C, const values (and pointers and references) cannot be modified.
|
||||||
barRef += ". Hi!"; // Error, const references cannot be modified.
|
barRef += ". Hi!"; // Error, const references cannot be modified.
|
||||||
|
|
||||||
|
// Sidetrack: Before we talk more about references, we must introduce a concept
|
||||||
|
// called a temporary object. Suppose we have the following code:
|
||||||
|
string tempObjectFun() { ... }
|
||||||
|
string retVal = tempObjectFun();
|
||||||
|
|
||||||
|
// What happens in the second line is actually:
|
||||||
|
// - a string object is returned from `tempObjectFun`
|
||||||
|
// - a new string is constructed with the returned object as arugment to the
|
||||||
|
// constructor
|
||||||
|
// - the returned object is destroyed
|
||||||
|
// The returned object is called a temporary object. Temporary objects are
|
||||||
|
// created whenever a function returns an object, and they are destroyed at the
|
||||||
|
// end of the evaluation of the enclosing expression. So in this code:
|
||||||
|
foo(bar(tempObjectFun()))
|
||||||
|
|
||||||
|
// assuming `foo` and `bar` exist, the object returned from `tempObjectFun` is
|
||||||
|
// passed to `bar`, and it is destroyed before `foo` is called.
|
||||||
|
|
||||||
|
// Now back to references. The exception to the "at the end of the enclosing
|
||||||
|
// expression" rule is if a temporary object is bound to a const reference, in
|
||||||
|
// which case its life gets extended to the current scope:
|
||||||
|
|
||||||
|
void constReferenceTempObjectFun() {
|
||||||
|
// `constRef` gets the temporary object, and it is valid until the end of this
|
||||||
|
// function.
|
||||||
|
const string& constRef = tempObjectFun();
|
||||||
|
...
|
||||||
|
}
|
||||||
|
|
||||||
|
// Another kind of reference introduced in C++11 is specifically for temporary
|
||||||
|
// objects. You cannot have a variable of its type, but it takes precedence in
|
||||||
|
// overload resolution:
|
||||||
|
|
||||||
|
void someFun(string& s) { ... } // Regular reference
|
||||||
|
void someFun(string&& s) { ... } // Reference to temporary object
|
||||||
|
|
||||||
|
string foo;
|
||||||
|
someFun(foo); // Calls the version with regular reference
|
||||||
|
someFun(tempObjectFun()); // Calls the version with temporary reference
|
||||||
|
|
||||||
|
// For example, you will see these two versions of constructors for
|
||||||
|
// std::basic_string:
|
||||||
|
basic_string(const basic_string& other);
|
||||||
|
basic_string(basic_string&& other);
|
||||||
|
|
||||||
|
// Idea being if we are constructing a new string from a temporary object (which
|
||||||
|
// is going to be destroyed soon anyway), we can have a more efficient
|
||||||
|
// constructor that "salvages" parts of that temporary string. You will see this
|
||||||
|
// concept referred to as the move semantic.
|
||||||
|
|
||||||
//////////////////////////////////////////
|
//////////////////////////////////////////
|
||||||
// Classes and object-oriented programming
|
// Classes and object-oriented programming
|
||||||
//////////////////////////////////////////
|
//////////////////////////////////////////
|
||||||
|
Loading…
Reference in New Issue
Block a user