From ebdde372443c0fe51b2513c9bfcfad8378ae52cd Mon Sep 17 00:00:00 2001 From: Riku-Pekka Silvola Date: Wed, 25 Feb 2015 18:10:57 +0100 Subject: fixed some typos --- c++.html.markdown | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'c++.html.markdown') diff --git a/c++.html.markdown b/c++.html.markdown index 5f80f26f..67fa054c 100644 --- a/c++.html.markdown +++ b/c++.html.markdown @@ -492,7 +492,7 @@ bool doSomethingWithAFile(const char* filename) { FILE* fh = fopen(filename, "r"); // Open the file in read mode if (fh == nullptr) // The returned pointer is null on failure. - reuturn false; // Report that failure to the caller. + return false; // Report that failure to the caller. // Assume each function returns false if it failed if (!doSomethingWithTheFile(fh)) { @@ -513,7 +513,7 @@ bool doSomethingWithAFile(const char* filename) { FILE* fh = fopen(filename, "r"); if (fh == nullptr) - reuturn false; + return false; if (!doSomethingWithTheFile(fh)) goto failure; -- cgit v1.2.3 From c88c28058b34c84de853694eb71d402fee937168 Mon Sep 17 00:00:00 2001 From: Arnie97 Date: Fri, 13 Mar 2015 23:40:45 +0800 Subject: Closes #1000 --- c++.html.markdown | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'c++.html.markdown') diff --git a/c++.html.markdown b/c++.html.markdown index 67fa054c..1978d183 100644 --- a/c++.html.markdown +++ b/c++.html.markdown @@ -30,10 +30,10 @@ one of the most widely-used programming languages. // C++ is _almost_ a superset of C and shares its basic syntax for // variable declarations, primitive types, and functions. -// However, C++ varies in some of the following ways: -// A main() function in C++ should return an int, -// though void main() is accepted by most compilers (gcc, clang, etc.) +// Just like in C, your program's entry point is a function called +// main with an integer return type, +// though void main() is also accepted by most compilers (gcc, clang, etc.) // This value serves as the program's exit status. // See http://en.wikipedia.org/wiki/Exit_status for more information. int main(int argc, char** argv) @@ -51,6 +51,8 @@ int main(int argc, char** argv) return 0; } +// However, C++ varies in some of the following ways: + // In C++, character literals are one byte. sizeof('c') == 1 -- cgit v1.2.3 From 299f3de0eacfe4e3d1303135716ad14a09bb0118 Mon Sep 17 00:00:00 2001 From: Arnie97 Date: Sat, 11 Apr 2015 12:52:23 +0800 Subject: [c++/en] Fix spelling --- 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 1978d183..1a84efa4 100644 --- a/c++.html.markdown +++ b/c++.html.markdown @@ -555,7 +555,7 @@ void doSomethingWithAFile(const char* filename) // Compare this to the use of C++'s file stream class (fstream) // fstream uses its destructor to close the file. // Recall from above that destructors are automatically called -// whenver an object falls out of scope. +// whenever an object falls out of scope. void doSomethingWithAFile(const std::string& filename) { // ifstream is short for input file stream -- cgit v1.2.3 From 7d5368eda1e2402b6b2bed85586fde0c6af87816 Mon Sep 17 00:00:00 2001 From: MoreMoschops Date: Sun, 26 Apr 2015 15:33:29 +0100 Subject: Neither gcc nor clang accept void main. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Neither gcc nor clang accept void main. Remove this bad information. Tested as follows: $ cat 045.cpp void main() { } $ g++ 045.cpp 045.cpp:1:11: error: ‘::main’ must return ‘int’ void main() ^ $ clang++ 045.cpp 045.cpp:1:1: error: 'main' must return 'int' void main() ^~~~ int 1 error generated. $ g++ --version g++ (Ubuntu 4.8.2-19ubuntu1) 4.8.2 $ clang++ --version Ubuntu clang version 3.4.2-3ubuntu2~xedgers (tags/RELEASE_34/dot2-final) (based on LLVM 3.4.2) --- c++.html.markdown | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'c++.html.markdown') diff --git a/c++.html.markdown b/c++.html.markdown index 1a84efa4..ae93ceba 100644 --- a/c++.html.markdown +++ b/c++.html.markdown @@ -32,8 +32,7 @@ one of the most widely-used programming languages. // variable declarations, primitive types, and functions. // Just like in C, your program's entry point is a function called -// main with an integer return type, -// though void main() is also accepted by most compilers (gcc, clang, etc.) +// main with an integer return type. // This value serves as the program's exit status. // See http://en.wikipedia.org/wiki/Exit_status for more information. int main(int argc, char** argv) -- cgit v1.2.3 From c21cf5a1e230dadf81bc4e31e2d2f9133551b365 Mon Sep 17 00:00:00 2001 From: Geoff Liu Date: Mon, 4 May 2015 02:40:04 -0600 Subject: Templates and such --- c++.html.markdown | 102 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 102 insertions(+) (limited to 'c++.html.markdown') diff --git a/c++.html.markdown b/c++.html.markdown index ae93ceba..10c39c9c 100644 --- a/c++.html.markdown +++ b/c++.html.markdown @@ -432,6 +432,81 @@ int main () { return 0; } +///////////////////// +// Templates +///////////////////// + +// Templates in C++ are mostly used for generic programming, though they are +// much more powerful than generics constructs in other languages. It also +// supports explicit and partial specialization, functional-style type classes, +// and also it's Turing-complete. + +// We start with the kind of generic programming you might be familiar with. To +// define a class or function that takes a type parameter: +template +class Box { + // In this class, T can be used as any other type. + void insert(const T&) { ... } +}; + +// During compilation, the compiler actually generates copies of each template +// with parameters substituted, and so the full definition of the class must be +// present at each invocation. This is why you will see template classes defined +// entirely in header files. + +// To instantiate a template class on the stack: +Box intBox; + +// and you can use it as you would expect: +intBox.insert(123); + +// You can, of course, nest templates: +Box > boxOfBox; +boxOfBox.insert(intBox); + +// Up until C++11, you muse place a space between the two '>'s, otherwise '>>' +// will be parsed as the right shift operator. + +// You will sometimes see +// template +// instead. The 'class' keyword and 'typename' keyword are _mostly_ +// interchangeable in this case. For full explanation, see +// http://en.wikipedia.org/wiki/Typename +// (yes, that keyword has its own Wikipedia page). + +// Similarly, a template function: +template +void barkThreeTimes(const T& input) +{ + input.bark(); + input.bark(); + input.bark(); +} + +// Notice that nothing is specified about the type parameters here. The compiler +// will generate and then type-check every invocation of the template, so the +// above function works with any type 'T' that has a const 'bark' method! + +Dog fluffy; +fluffy.setName("Fluffy") +barkThreeTimes(fluffy); Prints "Fluffy barks" three times. + +// Template parameters don't have to be classes, though this is used very rarely: +template +void printMessage() { + cout << "Learn C++ in " << Y << " minutes!" << endl; +} + +// And you can explicitly specialize templates for more efficient code: +template<> +void printMessage<10>() { + cout << "Learn C++ faster in only 10 minutes!" << endl; +} + +printMessage<20>(); // Prints "Learn C++ in 20 minutes!" +printMessage<10>(); // Prints "Learn C++ faster in only 10 minutes!" + + ///////////////////// // Exception Handling ///////////////////// @@ -585,6 +660,33 @@ void doSomethingWithAFile(const std::string& filename) // vector (i.e. self-resizing array), hash maps, and so on // all automatically destroy their contents when they fall out of scope. // - Mutexes using lock_guard and unique_lock + + +///////////////////// +// Fun stuff +///////////////////// + +// Aspects of C++ that may be surprising to newcomers (and even some veterans): + +// You can override private methods! +class Foo { + virtual void bar(); +}; +class FooSub : public Foo { + virtual void bar(); // overrides Foo::bar! +}; + +// 0, false, NULL are all the same thing! +bool* pt = new bool; +*pt = 0; // Sets the value points by 'pt' to false. +pt = 0; // Sets 'pt' to the null pointer. Yes both lines compile without warning. + +// '=' != '=' +Foo f1 = f2; // Calls Foo::Foo(const Foo&) or some variant copy constructor. + +Foo f1; +f1 = f2; // Calls Foo::operator=(Foo&) or variant. + ``` Futher Reading: -- cgit v1.2.3 From 05c2617aaf6d040b1e4372d8f83df11288ff2279 Mon Sep 17 00:00:00 2001 From: Geoff Liu Date: Mon, 4 May 2015 02:45:31 -0600 Subject: Minor fix --- 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 10c39c9c..e50c33fa 100644 --- a/c++.html.markdown +++ b/c++.html.markdown @@ -489,15 +489,16 @@ void barkThreeTimes(const T& input) Dog fluffy; fluffy.setName("Fluffy") -barkThreeTimes(fluffy); Prints "Fluffy barks" three times. +barkThreeTimes(fluffy); // Prints "Fluffy barks" three times. -// Template parameters don't have to be classes, though this is used very rarely: +// Template parameters don't have to be classes: template void printMessage() { cout << "Learn C++ in " << Y << " minutes!" << endl; } -// And you can explicitly specialize templates for more efficient code: +// And you can explicitly specialize templates for more efficient code (most +// real-world uses of specialization are not as trivial as this): template<> void printMessage<10>() { cout << "Learn C++ faster in only 10 minutes!" << endl; -- cgit v1.2.3 From 6c635d1c3e5bb88940fb0afb01218d2e7d3f11c0 Mon Sep 17 00:00:00 2001 From: Geoff Liu Date: Tue, 5 May 2015 00:45:14 -0600 Subject: Response to comments --- c++.html.markdown | 39 +++++++++++++++++++++++++++++++-------- 1 file changed, 31 insertions(+), 8 deletions(-) (limited to 'c++.html.markdown') diff --git a/c++.html.markdown b/c++.html.markdown index e50c33fa..517ce367 100644 --- a/c++.html.markdown +++ b/c++.html.markdown @@ -497,8 +497,10 @@ void printMessage() { cout << "Learn C++ in " << Y << " minutes!" << endl; } -// And you can explicitly specialize templates for more efficient code (most -// real-world uses of specialization are not as trivial as this): +// And you can explicitly specialize templates for more efficient code. Of +// course, most real-world uses of specialization are not as trivial as this. +// Note that you still need to declare the function (or class) as a template +// even if you explicitly specified all parameters. template<> void printMessage<10>() { cout << "Learn C++ faster in only 10 minutes!" << endl; @@ -667,7 +669,9 @@ void doSomethingWithAFile(const std::string& filename) // Fun stuff ///////////////////// -// Aspects of C++ that may be surprising to newcomers (and even some veterans): +// Aspects of C++ that may be surprising to newcomers (and even some veterans). +// This section is, unfortunately, wildly incomplete; C++ is one of the easiest +// languages with which to shoot yourself in the foot. // You can override private methods! class Foo { @@ -677,16 +681,35 @@ class FooSub : public Foo { virtual void bar(); // overrides Foo::bar! }; -// 0, false, NULL are all the same thing! + +// 0 == false == NULL (most of the time)! bool* pt = new bool; *pt = 0; // Sets the value points by 'pt' to false. -pt = 0; // Sets 'pt' to the null pointer. Yes both lines compile without warning. +pt = 0; // Sets 'pt' to the null pointer. Both lines compile without warnings. + +// nullptr is supposed to fix some of that issue: +int* pt2 = new int; +*pt2 = nullptr; // Doesn't compile +pt2 = nullptr; // Sets pt2 to null. + +// But somehow 'bool' type is an exception. +*pt = nullptr; // This still compiles, even though '*pt' is a bool! + + +// '=' != '=' != '='! +// Calls Foo::Foo(const Foo&) or some variant copy constructor. +Foo f2; +Foo f1 = f2; -// '=' != '=' -Foo f1 = f2; // Calls Foo::Foo(const Foo&) or some variant copy constructor. +// Calls Foo::Foo(const Foo&) or variant, but only copies the 'Foo' part of +// 'fooSub'. Any extra members of 'fooSub' are discarded. This lovely behavior +// is called "object slicing." +FooSub fooSub; +Foo f1 = fooSub; +// Calls Foo::operator=(Foo&) or variant. Foo f1; -f1 = f2; // Calls Foo::operator=(Foo&) or variant. +f1 = f2; ``` Futher Reading: -- cgit v1.2.3 From 25bd06d77a70964acfbdbf8a7c7a50eb312eae9f Mon Sep 17 00:00:00 2001 From: Geoff Liu Date: Wed, 6 May 2015 15:25:28 -0600 Subject: comment changes --- c++.html.markdown | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'c++.html.markdown') diff --git a/c++.html.markdown b/c++.html.markdown index 517ce367..66d4aeb1 100644 --- a/c++.html.markdown +++ b/c++.html.markdown @@ -692,7 +692,7 @@ int* pt2 = new int; *pt2 = nullptr; // Doesn't compile pt2 = nullptr; // Sets pt2 to null. -// But somehow 'bool' type is an exception. +// But somehow 'bool' type is an exception (this is to make `if (ptr)` compile). *pt = nullptr; // This still compiles, even though '*pt' is a bool! @@ -702,8 +702,8 @@ Foo f2; Foo f1 = f2; // Calls Foo::Foo(const Foo&) or variant, but only copies the 'Foo' part of -// 'fooSub'. Any extra members of 'fooSub' are discarded. This lovely behavior -// is called "object slicing." +// 'fooSub'. Any extra members of 'fooSub' are discarded. This sometimes +// horrifying behavior is called "object slicing." FooSub fooSub; Foo f1 = fooSub; -- cgit v1.2.3 From bad283ee14dadd02f9b21d5fbcff226bfb5c954f Mon Sep 17 00:00:00 2001 From: Hans Ole Hatzel Date: Wed, 20 May 2015 19:38:11 +0200 Subject: [c++/en] Fixed typos. --- c++.html.markdown | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'c++.html.markdown') diff --git a/c++.html.markdown b/c++.html.markdown index 66d4aeb1..9f8f5f32 100644 --- a/c++.html.markdown +++ b/c++.html.markdown @@ -425,7 +425,7 @@ int main () { Point up (0,1); Point right (1,0); // This calls the Point + operator - // Point up calls the + (function) with right as its paramater + // Point up calls the + (function) with right as its parameter Point result = up + right; // Prints "Result is upright (1,1)" cout << "Result is upright (" << result.x << ',' << result.y << ")\n"; @@ -464,7 +464,7 @@ intBox.insert(123); Box > boxOfBox; boxOfBox.insert(intBox); -// Up until C++11, you muse place a space between the two '>'s, otherwise '>>' +// Up until C++11, you must place a space between the two '>'s, otherwise '>>' // will be parsed as the right shift operator. // You will sometimes see @@ -712,7 +712,7 @@ Foo f1; f1 = f2; ``` -Futher Reading: +Further Reading: An up-to-date language reference can be found at -- cgit v1.2.3 From 462ac892179d64437b1124263402378a6054e50b Mon Sep 17 00:00:00 2001 From: Adam Date: Sun, 31 May 2015 21:38:03 -0400 Subject: Remove return type from Dog class constructor and destructor, change nonexistant printDog function to print. --- c++.html.markdown | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'c++.html.markdown') diff --git a/c++.html.markdown b/c++.html.markdown index 9f8f5f32..2c6d51a9 100644 --- a/c++.html.markdown +++ b/c++.html.markdown @@ -300,7 +300,7 @@ public: }; // A semicolon must follow the class definition. // Class member functions are usually implemented in .cpp files. -void Dog::Dog() +Dog::Dog() { std::cout << "A dog has been constructed\n"; } @@ -323,7 +323,7 @@ void Dog::print() const std::cout << "Dog is " << name << " and weighs " << weight << "kg\n"; } -void Dog::~Dog() +Dog::~Dog() { cout << "Goodbye " << name << "\n"; } @@ -332,7 +332,7 @@ int main() { Dog myDog; // prints "A dog has been constructed" myDog.setName("Barkley"); myDog.setWeight(10); - myDog.printDog(); // prints "Dog is Barkley and weighs 10 kg" + myDog.print(); // prints "Dog is Barkley and weighs 10 kg" return 0; } // prints "Goodbye Barkley" -- cgit v1.2.3 From 3db1042157204ad05484d6b42140261f849040cc Mon Sep 17 00:00:00 2001 From: Adam Date: Sun, 31 May 2015 21:42:03 -0400 Subject: Add missing semicolons. --- c++.html.markdown | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'c++.html.markdown') diff --git a/c++.html.markdown b/c++.html.markdown index 2c6d51a9..5cd491b9 100644 --- a/c++.html.markdown +++ b/c++.html.markdown @@ -288,7 +288,7 @@ public: // Functions can also be defined inside the class body. // Functions defined as such are automatically inlined. - void bark() const { std::cout << name << " barks!\n" } + void bark() const { std::cout << name << " barks!\n"; } // Along with constructors, C++ provides destructors. // These are called when an object is deleted or falls out of scope. @@ -341,7 +341,7 @@ int main() { // This class inherits everything public and protected from the Dog class class OwnedDog : public Dog { - void setOwner(const std::string& dogsOwner) + void setOwner(const std::string& dogsOwner); // Override the behavior of the print function for all OwnedDogs. See // http://en.wikipedia.org/wiki/Polymorphism_(computer_science)#Subtyping -- cgit v1.2.3 From cea52ca43490b74316781c23779654fd46aaeab4 Mon Sep 17 00:00:00 2001 From: Adam Date: Mon, 1 Jun 2015 21:57:18 -0400 Subject: Exceptions do not take a string argument in their constructor. --- c++.html.markdown | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'c++.html.markdown') diff --git a/c++.html.markdown b/c++.html.markdown index 5cd491b9..b214de7a 100644 --- a/c++.html.markdown +++ b/c++.html.markdown @@ -523,7 +523,7 @@ printMessage<10>(); // Prints "Learn C++ faster in only 10 minutes!" // _catch_ handlers. try { // Do not allocate exceptions on the heap using _new_. - throw std::exception("A problem occurred"); + throw std::exception(); } // Catch exceptions by const reference if they are objects catch (const std::exception& ex) @@ -614,7 +614,7 @@ void doSomethingWithAFile(const char* filename) { FILE* fh = fopen(filename, "r"); // Open the file in read mode if (fh == nullptr) - throw std::exception("Could not open the file."); + throw std::exception(); try { doSomethingWithTheFile(fh); -- cgit v1.2.3 From 47d3cea47e8c5203efa857070a00dcfbff67b019 Mon Sep 17 00:00:00 2001 From: Adam Date: Mon, 1 Jun 2015 22:00:52 -0400 Subject: Template example class should have public method so it can get called externally. --- c++.html.markdown | 1 + 1 file changed, 1 insertion(+) (limited to 'c++.html.markdown') diff --git a/c++.html.markdown b/c++.html.markdown index b214de7a..d049408a 100644 --- a/c++.html.markdown +++ b/c++.html.markdown @@ -445,6 +445,7 @@ int main () { // define a class or function that takes a type parameter: template class Box { +public: // In this class, T can be used as any other type. void insert(const T&) { ... } }; -- cgit v1.2.3 From 894792e1e17173823a5d50de24439427c69d63f4 Mon Sep 17 00:00:00 2001 From: Adam Date: Tue, 2 Jun 2015 16:30:35 -0400 Subject: Using std::runtime_error instead of std::exception. --- 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 d049408a..6f4d2959 100644 --- a/c++.html.markdown +++ b/c++.html.markdown @@ -519,12 +519,13 @@ printMessage<10>(); // Prints "Learn C++ faster in only 10 minutes!" // (see http://en.cppreference.com/w/cpp/error/exception) // but any type can be thrown an as exception #include +#include // All exceptions thrown inside the _try_ block can be caught by subsequent // _catch_ handlers. try { // Do not allocate exceptions on the heap using _new_. - throw std::exception(); + throw std::runtime_error("A problem occurred"); } // Catch exceptions by const reference if they are objects catch (const std::exception& ex) -- cgit v1.2.3 From 06889be239622266d9c36c750f7ee755ccdae05d Mon Sep 17 00:00:00 2001 From: Adam Date: Tue, 2 Jun 2015 19:14:52 -0400 Subject: Updated other exception to also be runtime_error type instead. --- 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 6f4d2959..ff2a98fd 100644 --- a/c++.html.markdown +++ b/c++.html.markdown @@ -616,7 +616,7 @@ void doSomethingWithAFile(const char* filename) { FILE* fh = fopen(filename, "r"); // Open the file in read mode if (fh == nullptr) - throw std::exception(); + throw std::runtime_error("Could not open the file."); try { doSomethingWithTheFile(fh); -- cgit v1.2.3 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 From ae86e4ebabb0c78c1bd8052e6ab5916446ef39c2 Mon Sep 17 00:00:00 2001 From: Alva Connor Waters Date: Fri, 2 Oct 2015 15:19:38 +0000 Subject: Clarify character literals --- c++.html.markdown | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'c++.html.markdown') diff --git a/c++.html.markdown b/c++.html.markdown index 8a7f5a59..1cf5508a 100644 --- a/c++.html.markdown +++ b/c++.html.markdown @@ -53,11 +53,11 @@ int main(int argc, char** argv) // However, C++ varies in some of the following ways: -// In C++, character literals are one byte. -sizeof('c') == 1 +// In C++, character literals are chars +sizeof('c') == sizeof(char) == 1 -// In C, character literals are the same size as ints. -sizeof('c') == sizeof(10) +// In C, character literals are ints +sizeof('c') == sizeof(int) // C++ has strict prototyping -- cgit v1.2.3 From 455afa3a7bf59fc272f3439825da55659765eec0 Mon Sep 17 00:00:00 2001 From: Alva Connor Waters Date: Fri, 2 Oct 2015 15:55:05 +0000 Subject: More explanation on virtual destructors --- 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 1cf5508a..b59635f5 100644 --- a/c++.html.markdown +++ b/c++.html.markdown @@ -349,7 +349,10 @@ public: // These are called when an object is deleted or falls out of scope. // This enables powerful paradigms such as RAII // (see below) - // Destructors must be virtual to allow classes to be derived from this one. + // Destructors should be virtual if a class is to be derived from; + // if they are not virtual, then any resources allocated using RAII in + // the derived class will not be released if it destroyed through a + // base-class reference or pointer. virtual ~Dog(); }; // A semicolon must follow the class definition. -- cgit v1.2.3 From 12286a4b78f82bde3907d4bf348e20c12dd6d46f Mon Sep 17 00:00:00 2001 From: Alva Connor Waters Date: Fri, 2 Oct 2015 16:00:13 +0000 Subject: Misc. typos and formatting --- c++.html.markdown | 72 ++++++++++++++++++++++++++++++------------------------- 1 file changed, 39 insertions(+), 33 deletions(-) (limited to 'c++.html.markdown') diff --git a/c++.html.markdown b/c++.html.markdown index b59635f5..e5eceac1 100644 --- a/c++.html.markdown +++ b/c++.html.markdown @@ -159,9 +159,9 @@ void foo() int main() { - // 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. + // Includes all symbols from namespace 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; Second::foo(); // prints "This is Second::foo" @@ -256,7 +256,7 @@ string tempObjectFun() { ... } string retVal = tempObjectFun(); // What happens in the second line is actually: -// - a string object is returned from `tempObjectFun` +// - 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 @@ -268,15 +268,15 @@ string retVal = tempObjectFun(); // 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. +// 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 + // constRef gets the temporary object, and it is valid until the end of this // function. const string& constRef = tempObjectFun(); ... @@ -301,7 +301,7 @@ 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. +// concept referred to as "move semantics". ////////////////////////////////////////// // Classes and object-oriented programming @@ -349,10 +349,10 @@ public: // These are called when an object is deleted or falls out of scope. // This enables powerful paradigms such as RAII // (see below) - // Destructors should be virtual if a class is to be derived from; - // if they are not virtual, then any resources allocated using RAII in - // the derived class will not be released if it destroyed through a - // base-class reference or pointer. + // The destructor should be virtual if a class is to be derived from; + // if it is not virtual, then the derived class' destructor will + // not be called if the object is destroyed through a base-class reference + // or pointer. virtual ~Dog(); }; // A semicolon must follow the class definition. @@ -495,9 +495,10 @@ int main () { ///////////////////// // Templates in C++ are mostly used for generic programming, though they are -// much more powerful than generics constructs in other languages. It also -// supports explicit and partial specialization, functional-style type classes, -// and also it's Turing-complete. +// much more powerful than generic constructs in other languages. They also +// support explicit and partial specialization and functional-style type +// classes; in fact, they are a Turing-complete functional language embedded +// in C++! // We start with the kind of generic programming you might be familiar with. To // define a class or function that takes a type parameter: @@ -509,7 +510,7 @@ public: }; // During compilation, the compiler actually generates copies of each template -// with parameters substituted, and so the full definition of the class must be +// with parameters substituted, so the full definition of the class must be // present at each invocation. This is why you will see template classes defined // entirely in header files. @@ -523,13 +524,13 @@ intBox.insert(123); Box > boxOfBox; boxOfBox.insert(intBox); -// Up until C++11, you must place a space between the two '>'s, otherwise '>>' -// will be parsed as the right shift operator. +// Until C++11, you had to place a space between the two '>'s, otherwise '>>' +// would be parsed as the right shift operator. // You will sometimes see // template -// instead. The 'class' keyword and 'typename' keyword are _mostly_ -// interchangeable in this case. For full explanation, see +// instead. The 'class' keyword and 'typename' keywords are _mostly_ +// interchangeable in this case. For the full explanation, see // http://en.wikipedia.org/wiki/Typename // (yes, that keyword has its own Wikipedia page). @@ -585,12 +586,15 @@ try { // Do not allocate exceptions on the heap using _new_. throw std::runtime_error("A problem occurred"); } + // Catch exceptions by const reference if they are objects catch (const std::exception& ex) { - std::cout << ex.what(); + std::cout << ex.what(); +} + // Catches any exception not caught by previous _catch_ blocks -} catch (...) +catch (...) { std::cout << "Unknown exception caught"; throw; // Re-throws the exception @@ -600,8 +604,8 @@ catch (const std::exception& ex) // RAII /////// -// RAII stands for Resource Allocation Is Initialization. -// It is often considered the most powerful paradigm in C++, +// RAII stands for "Resource Acquisition Is Initialization". +// It is often considered the most powerful paradigm in C++ // and is the simple concept that a constructor for an object // acquires that object's resources and the destructor releases them. @@ -622,9 +626,9 @@ void doSomethingWithAFile(const char* filename) // Unfortunately, things are quickly complicated by error handling. // Suppose fopen can fail, and that doSomethingWithTheFile and // doSomethingElseWithIt return error codes if they fail. -// (Exceptions are the preferred way of handling failure, -// but some programmers, especially those with a C background, -// disagree on the utility of exceptions). +// (Exceptions are the preferred way of handling failure, +// but some programmers, especially those with a C background, +// disagree on the utility of exceptions). // We now have to check each call for failure and close the file handle // if a problem occurred. bool doSomethingWithAFile(const char* filename) @@ -744,15 +748,17 @@ class FooSub : public Foo { // 0 == false == NULL (most of the time)! bool* pt = new bool; -*pt = 0; // Sets the value points by 'pt' to false. +*pt = 0; // Sets the value points by 'pt' to false. pt = 0; // Sets 'pt' to the null pointer. Both lines compile without warnings. // nullptr is supposed to fix some of that issue: int* pt2 = new int; -*pt2 = nullptr; // Doesn't compile +*pt2 = nullptr; // Doesn't compile pt2 = nullptr; // Sets pt2 to null. -// But somehow 'bool' type is an exception (this is to make `if (ptr)` compile). +// There is an exception made for bools. +// This is to allow you to test for null pointers with if(!ptr), +// but as a consequence you can assign nullptr to a bool directly! *pt = nullptr; // This still compiles, even though '*pt' is a bool! @@ -779,12 +785,12 @@ 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, +// 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. +v.push_back(Foo()); // New value is copied into the first Foo we inserted -// Truly destroys all values in v. See section about temporary object for +// Truly destroys all values in v. See section about temporary objects for // explanation of why this works. v.swap(vector()); -- cgit v1.2.3 From c4b8281ceeed59ddfa003cc95e40944735d1c910 Mon Sep 17 00:00:00 2001 From: Alva Connor Waters Date: Fri, 2 Oct 2015 16:19:29 +0000 Subject: Add to contributors --- c++.html.markdown | 1 + 1 file changed, 1 insertion(+) (limited to 'c++.html.markdown') diff --git a/c++.html.markdown b/c++.html.markdown index e5eceac1..4acc1b9d 100644 --- a/c++.html.markdown +++ b/c++.html.markdown @@ -5,6 +5,7 @@ contributors: - ["Steven Basart", "http://github.com/xksteven"] - ["Matt Kline", "https://github.com/mrkline"] - ["Geoff Liu", "http://geoffliu.me"] + - ["Connor Waters", "http://github.com/connorwaters"] lang: en --- -- cgit v1.2.3 From 9bc553c46ce9b7154ec7c82451d71608f4beda82 Mon Sep 17 00:00:00 2001 From: Pushkar Sharma Date: Sun, 4 Oct 2015 10:12:55 +0530 Subject: Update c++.html.markdown Regarding issue #1216, Better explaining the Reference 'fooRef'. --- c++.html.markdown | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'c++.html.markdown') diff --git a/c++.html.markdown b/c++.html.markdown index 4acc1b9d..bbd2f9a9 100644 --- a/c++.html.markdown +++ b/c++.html.markdown @@ -245,7 +245,13 @@ cout << fooRef; // Prints "I am foo. Hi!" // Doesn't reassign "fooRef". This is the same as "foo = bar", and // foo == "I am bar" // after this line. +cout << &fooRef << endl; //Prints address of fooRef fooRef = bar; +cout << &fooRef << endl; //Prints address of fooRef, AGAIN +cout << fooRef; // Prints "I am bar" + +//The address of fooRef remains the same, i.e. it is still referring to foo. + const string& barRef = bar; // Create a const reference to bar. // Like C, const values (and pointers and references) cannot be modified. -- cgit v1.2.3 From 87e8e77e5fd8d84a252dbb6d6697202118378774 Mon Sep 17 00:00:00 2001 From: Pushkar Sharma Date: Mon, 5 Oct 2015 00:13:54 +0530 Subject: Fixed a mistake from previous commit. Better explained reference address. --- c++.html.markdown | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'c++.html.markdown') diff --git a/c++.html.markdown b/c++.html.markdown index bbd2f9a9..bd86e9e5 100644 --- a/c++.html.markdown +++ b/c++.html.markdown @@ -245,9 +245,9 @@ cout << fooRef; // Prints "I am foo. Hi!" // Doesn't reassign "fooRef". This is the same as "foo = bar", and // foo == "I am bar" // after this line. -cout << &fooRef << endl; //Prints address of fooRef +cout << &fooRef << endl; //Prints address of foo fooRef = bar; -cout << &fooRef << endl; //Prints address of fooRef, AGAIN +cout << &fooRef << endl; //Still prints address of foo cout << fooRef; // Prints "I am bar" //The address of fooRef remains the same, i.e. it is still referring to foo. -- cgit v1.2.3 From 3b246fd869564b0a7f7c847f44aecac82d318c78 Mon Sep 17 00:00:00 2001 From: Pushkar Sharma Date: Mon, 5 Oct 2015 00:32:34 +0530 Subject: Grammar the address --- c++.html.markdown | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'c++.html.markdown') diff --git a/c++.html.markdown b/c++.html.markdown index bd86e9e5..8ee964ca 100644 --- a/c++.html.markdown +++ b/c++.html.markdown @@ -245,9 +245,9 @@ cout << fooRef; // Prints "I am foo. Hi!" // Doesn't reassign "fooRef". This is the same as "foo = bar", and // foo == "I am bar" // after this line. -cout << &fooRef << endl; //Prints address of foo +cout << &fooRef << endl; //Prints the address of foo fooRef = bar; -cout << &fooRef << endl; //Still prints address of foo +cout << &fooRef << endl; //Still prints the address of foo cout << fooRef; // Prints "I am bar" //The address of fooRef remains the same, i.e. it is still referring to foo. -- cgit v1.2.3 From 9d64b532f8ccdfd95c2417dcf65257385956353a Mon Sep 17 00:00:00 2001 From: George Gognadze Date: Wed, 7 Oct 2015 01:27:12 +0400 Subject: Update c++.html.markdown spelling error --- 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 8ee964ca..6f4d0562 100644 --- a/c++.html.markdown +++ b/c++.html.markdown @@ -264,7 +264,7 @@ 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 +// - a new string is constructed with the returned object as argument to the // constructor // - the returned object is destroyed // The returned object is called a temporary object. Temporary objects are -- cgit v1.2.3 From e32eb715ef41e411da0a91b40e6e35f150a9c2eb Mon Sep 17 00:00:00 2001 From: Cameron Wood Date: Sun, 11 Oct 2015 03:41:20 -0400 Subject: [C++/en] Small inheritance clarification Clarified that private members are inherited but are not directly accessible --- c++.html.markdown | 2 ++ 1 file changed, 2 insertions(+) (limited to 'c++.html.markdown') diff --git a/c++.html.markdown b/c++.html.markdown index 6f4d0562..2bee51dc 100644 --- a/c++.html.markdown +++ b/c++.html.markdown @@ -404,6 +404,8 @@ int main() { // Inheritance: // This class inherits everything public and protected from the Dog class +// as well as private but may not directly access private members/methods +// without a public or protected method for doing so class OwnedDog : public Dog { void setOwner(const std::string& dogsOwner); -- cgit v1.2.3 From ca435fbb0dd09cdc9c70fe945a891ae3e6c19ab2 Mon Sep 17 00:00:00 2001 From: Cameron Wood Date: Sat, 17 Oct 2015 06:05:54 -0400 Subject: [C++/en] Added in Enum information Added in some information about enums in C++ including some different use cases --- c++.html.markdown | 64 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) (limited to 'c++.html.markdown') diff --git a/c++.html.markdown b/c++.html.markdown index 2bee51dc..d03092e5 100644 --- a/c++.html.markdown +++ b/c++.html.markdown @@ -310,6 +310,70 @@ basic_string(basic_string&& other); // constructor that "salvages" parts of that temporary string. You will see this // concept referred to as "move semantics". +///////////////////// +// Enums +///////////////////// + +// Enums are a way to assign a value to a constant most commonly used for +// easier visualization and reading of code +enum ECarTypes +{ + Sedan, + Hatchback, + SUV, + Wagon +}; + +ECarTypes GetPreferredCarType() +{ + return ECarTypes::Hatchback; +} + +// As of C++11 there is an easy way to assign a type to the enum which can be +// useful in serialization of data and converting enums back-and-forth between +// the desired type and their respective constants +enum ECarTypes : uint8_t +{ + Sedan, // 0 + Hatchback, // 1 + SUV = 254, // 254 + Hybrid // 255 +}; + +void WriteByteToFile(uint8_t InputValue) +{ + // Serialize the InputValue to a file +} + +void WritePreferredCarTypeToFile(ECarTypes InputCarType) +{ + // The enum is implicitly converted to a uint8_t due to its declared enum type + WriteByteToFile(InputCarType); +} + +// On the other hand you may not want enums to be accidentally cast to an integer +// type or to other enums so it is instead possible to create an enum class which +// won't be implicitly converted +enum class ECarTypes : uint8_t +{ + Sedan, // 0 + Hatchback, // 1 + SUV = 254, // 254 + Hybrid // 255 +}; + +void WriteByteToFile(uint8_t InputValue) +{ + // Serialize the InputValue to a file +} + +void WritePreferredCarTypeToFile(ECarTypes InputCarType) +{ + // Won't compile even though ECarTypes is a uint8_t due to the enum + // being declared as an "enum class"! + WriteByteToFile(InputCarType); +} + ////////////////////////////////////////// // Classes and object-oriented programming ////////////////////////////////////////// -- cgit v1.2.3 From c3e769e4ac50d4475a530969663e073f4ff002ca Mon Sep 17 00:00:00 2001 From: Brook Zhou Date: Sat, 31 Oct 2015 16:17:58 -0700 Subject: [cpp/en] comparator function for std containers --- c++.html.markdown | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'c++.html.markdown') diff --git a/c++.html.markdown b/c++.html.markdown index d03092e5..6b452b1b 100644 --- a/c++.html.markdown +++ b/c++.html.markdown @@ -801,6 +801,24 @@ void doSomethingWithAFile(const std::string& filename) // all automatically destroy their contents when they fall out of scope. // - Mutexes using lock_guard and unique_lock +// containers with object keys of non-primitive values (custom classes) require +// compare function in the object itself or as a function pointer. Primitives +// have default comparators, but you can override it. +class Foo { +public: + int j; + Foo(int a) : j(a) {} +}; +struct compareFunction { + bool operator()(const Foo& a, const Foo& b) const { + return a.j < b.j; + } +}; +//this isn't allowed (although it can vary depending on compiler) +//std::map fooMap; +std::map fooMap; +fooMap[Foo(1)] = 1; +fooMap.find(Foo(1)); //true ///////////////////// // Fun stuff -- cgit v1.2.3