From 97b97408eab97fbe322df4266cda9ab2ed21fceb Mon Sep 17 00:00:00 2001 From: Geoff Liu Date: Fri, 28 Aug 2015 11:48:38 -0600 Subject: Fix C++ namespace explanation --- c++.html.markdown | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'c++.html.markdown') diff --git a/c++.html.markdown b/c++.html.markdown index ff2a98fd..883d3482 100644 --- a/c++.html.markdown +++ b/c++.html.markdown @@ -158,11 +158,12 @@ void foo() int main() { - // Assume everything is from the namespace "Second" - // unless otherwise specified. + // Includes all symbols from `namesapce Second` into the current scope. Note + // that simply `foo()` no longer works, since it is now ambiguous whether + // we're calling the `foo` in `namespace Second` or the top level. using namespace Second; - foo(); // prints "This is Second::foo" + Second::foo(); // prints "This is Second::foo" First::Nested::foo(); // prints "This is First::Nested::foo" ::foo(); // prints "This is global foo" } -- cgit v1.2.3 From 1d1def16a5d7925bb8f7fba7dc49182e33359e85 Mon Sep 17 00:00:00 2001 From: Geoff Liu Date: Sun, 30 Aug 2015 14:20:18 -0600 Subject: A little more about C++ references --- c++.html.markdown | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) (limited to 'c++.html.markdown') diff --git a/c++.html.markdown b/c++.html.markdown index ff2a98fd..efce0053 100644 --- a/c++.html.markdown +++ b/c++.html.markdown @@ -4,6 +4,7 @@ filename: learncpp.cpp contributors: - ["Steven Basart", "http://github.com/xksteven"] - ["Matt Kline", "https://github.com/mrkline"] + - ["Geoff Liu", "http://geoffliu.me"] 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. 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 ////////////////////////////////////////// -- cgit v1.2.3 From a230d76307ecbc0f53c4b359cdb90628720f915e Mon Sep 17 00:00:00 2001 From: Geoff Liu Date: Sun, 30 Aug 2015 14:41:02 -0600 Subject: More about temporary objects --- c++.html.markdown | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'c++.html.markdown') diff --git a/c++.html.markdown b/c++.html.markdown index e45c73c3..74bd8913 100644 --- a/c++.html.markdown +++ b/c++.html.markdown @@ -765,6 +765,22 @@ Foo f1 = fooSub; Foo f1; f1 = f2; + +// How to truly clear a container: +class Foo { ... }; +vector v; +for (int i = 0; i < 10; ++i) + v.push_back(Foo()); + +// Following line sets size of v to 0, but destructors don't get called, +// and resources aren't released! +v.empty(); +v.push_back(Foo()); // New value is copied into the first Foo we inserted in the loop. + +// Truly destroys all values in v. See section about temporary object for +// explanation of why this works. +v.swap(vector()); + ``` Further Reading: -- cgit v1.2.3 From fc9ae44e4887500634bf3a87343d687b4d7d4e3c Mon Sep 17 00:00:00 2001 From: Geoff Liu Date: Sun, 30 Aug 2015 14:46:46 -0600 Subject: Now that we explained move semantics --- c++.html.markdown | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'c++.html.markdown') diff --git a/c++.html.markdown b/c++.html.markdown index 74bd8913..fa80e6d5 100644 --- a/c++.html.markdown +++ b/c++.html.markdown @@ -751,7 +751,8 @@ pt2 = nullptr; // Sets pt2 to null. // '=' != '=' != '='! -// Calls Foo::Foo(const Foo&) or some variant copy constructor. +// Calls Foo::Foo(const Foo&) or some variant (see move semantics) copy +// constructor. Foo f2; Foo f1 = f2; -- cgit v1.2.3 From 85f6ba0b57b9d894c694df66449b1e1c555c625b Mon Sep 17 00:00:00 2001 From: Geoff Liu Date: Wed, 2 Sep 2015 00:46:30 -0600 Subject: A note about RVO --- c++.html.markdown | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'c++.html.markdown') diff --git a/c++.html.markdown b/c++.html.markdown index fa80e6d5..26dfe111 100644 --- a/c++.html.markdown +++ b/c++.html.markdown @@ -262,7 +262,10 @@ string retVal = tempObjectFun(); // - 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: +// end of the evaluation of the enclosing expression (Well, this is what the +// standard says, but compilers are allowed to change this behavior. Look up +// "return value optimization" if you're into this kind of details). So in this +// code: foo(bar(tempObjectFun())) // assuming `foo` and `bar` exist, the object returned from `tempObjectFun` is -- cgit v1.2.3 From 8eb410208a8d9b0a42f6c52411455ace04c78101 Mon Sep 17 00:00:00 2001 From: George Gognadze Date: Thu, 1 Oct 2015 18:55:28 +0400 Subject: Update c++.html.markdown o should be capitalized. this: overrides should be: Overrides --- c++.html.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'c++.html.markdown') diff --git a/c++.html.markdown b/c++.html.markdown index 26dfe111..8a7f5a59 100644 --- a/c++.html.markdown +++ b/c++.html.markdown @@ -735,7 +735,7 @@ class Foo { virtual void bar(); }; class FooSub : public Foo { - virtual void bar(); // overrides Foo::bar! + virtual void bar(); // Overrides Foo::bar! }; -- cgit v1.2.3