diff --git a/5-UsefulConceptsAndSTL/2-RAII.ipynb b/5-UsefulConceptsAndSTL/2-RAII.ipynb index 1b60b7cabf1ff7816798b16c0b38817137968c7e..d376cee3db1e91940d1540c7e4bbb8cb6de37d11 100644 --- a/5-UsefulConceptsAndSTL/2-RAII.ipynb +++ b/5-UsefulConceptsAndSTL/2-RAII.ipynb @@ -4,7 +4,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "# [Getting started in C++](/) - [Useful concepts and STL](/notebooks/5-UsefulConceptsAndSTL/0-main.ipynb) - [RAII idiom](/notebooks/5-UsefulConceptsAndSTL/2-RAII.ipynb)" + "# [Getting started in C++](/) - [Useful concepts and STL](./0-main.ipynb) - [RAII idiom](./2-RAII.ipynb)" ] }, { @@ -27,7 +27,7 @@ "\n", "Often, people who criticizes the language say C++ is really tricky and that is extremely easy to leak memory all over the way, and that it sorely miss a [**garbage collector**](https://en.wikipedia.org/wiki/Garbage_collection_(computer_science)) which does the job of cleaning-up and freeing the memory when the data are no longer used.\n", "\n", - "However, garbage collection, used for instance in Python and Java, is not without issues itself: the memory is not always freed as swiftly as possible, and the bookkeeping of references is not without a toll on the efficiency of the program itself.\n", + "However, garbage collection, used for instance in Python and Java, is not without issues itself: the memory is not always freed as swiftly as possible, and the bookkeeping of references is not without a toll on the efficiency of the program.\n", "\n", "C++ provides in fact the best of both worlds: a way to provide safe freeing of memory as soon as possible... provided you know how to adequately use it.\n", "\n", @@ -152,7 +152,7 @@ "metadata": {}, "source": [ "\n", - "© _CNRS 2016_ - _Inria 2018-2019_ \n", + "© _CNRS 2016_ - _Inria 2018-2020_ \n", "_This notebook is an adaptation of a lecture prepared by David Chamont (CNRS) under the terms of the licence [Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0)](http://creativecommons.org/licenses/by-nc-sa/4.0/)_ \n", "_The present version has been written by Sébastien Gilles and Vincent Rouvreau (Inria)_" ] @@ -162,14 +162,14 @@ "kernelspec": { "display_name": "C++17", "language": "C++17", - "name": "xeus-cling-cpp17" + "name": "xcpp17" }, "language_info": { "codemirror_mode": "text/x-c++src", "file_extension": ".cpp", "mimetype": "text/x-c++src", "name": "c++", - "version": "-std=c++17" + "version": "17" }, "latex_envs": { "LaTeX_envs_menu_present": true, diff --git a/5-UsefulConceptsAndSTL/3-Containers.ipynb b/5-UsefulConceptsAndSTL/3-Containers.ipynb index 82be6e31c11a9c7a991a9d1b0fbe9f700b682bd2..86b63501c5134a59e5bc62ab854b6091d63c00d5 100644 --- a/5-UsefulConceptsAndSTL/3-Containers.ipynb +++ b/5-UsefulConceptsAndSTL/3-Containers.ipynb @@ -4,7 +4,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "# [Getting started in C++](/) - [Useful concepts and STL](/notebooks/5-UsefulConceptsAndSTL/0-main.ipynb) - [Containers](/notebooks/5-UsefulConceptsAndSTL/3-Containers.ipynb)" + "# [Getting started in C++](/) - [Useful concepts and STL](./0-main.ipynb) - [Containers](./3-Containers.ipynb)" ] }, { @@ -58,7 +58,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 1, "metadata": {}, "outputs": [], "source": [ @@ -77,9 +77,19 @@ }, { "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0\n", + "0\n", + "0\n" + ] + } + ], "source": [ "#include <vector>\n", "#include <iostream>\n", @@ -100,9 +110,19 @@ }, { "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "4.3\n", + "4.3\n", + "4.3\n" + ] + } + ], "source": [ "#include <vector>\n", "#include <iostream>\n", @@ -123,9 +143,19 @@ }, { "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "3\n", + "5\n", + "6\n" + ] + } + ], "source": [ "#include <vector>\n", "#include <iostream>\n", @@ -141,14 +171,24 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "* And of course copy and move constructions" + "* And of course copy (and move) constructions" ] }, { "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "3\n", + "5\n", + "6\n" + ] + } + ], "source": [ "#include <vector>\n", "#include <iostream>\n", @@ -177,9 +217,17 @@ }, { "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Size = 3\n" + ] + } + ], "source": [ "#include <vector>\n", "#include <iostream>\n", @@ -195,14 +243,23 @@ "source": [ "### Adding new elements\n", "\n", - "`std::vector` provides an easy and (most of the time) cheap to add an element **at the end of the array**. The method to add a new element is `push_back`:" + "`std::vector` provides an easy and (most of the time) cheap way to add an element **at the end of the array**. The method to add a new element is `push_back`:" ] }, { "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Size = 3\n", + "Size = 4\n" + ] + } + ], "source": [ "#include <vector>\n", "#include <iostream>\n", @@ -232,15 +289,23 @@ }, { "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "foo[1] = 5\n" + ] + } + ], "source": [ "#include <vector>\n", "#include <iostream>\n", "{\n", " std::vector<int> foo { 3, 5, 6 };\n", - " std::cout << \"foo[1] = \" << foo[1] << std::endl;\n", + " std::cout << \"foo[1] = \" << foo[1] << std::endl; // Remember: indexing starts at 0 in C and C++\n", "}" ] }, @@ -253,9 +318,17 @@ }, { "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "foo[4] = 0\n" + ] + } + ], "source": [ "#include <vector>\n", "#include <iostream>\n", @@ -274,9 +347,25 @@ }, { "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "foo[4] = " + ] + }, + { + "ename": "Standard Exception", + "evalue": "vector", + "output_type": "error", + "traceback": [ + "Standard Exception: vector" + ] + } + ], "source": [ "#include <vector>\n", "#include <iostream>\n", @@ -311,9 +400,26 @@ }, { "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Vector: size = 0 and capacity = 0\n", + "Vector: size = 1 and capacity = 1\n", + "Vector: size = 2 and capacity = 2\n", + "Vector: size = 3 and capacity = 4\n", + "Vector: size = 4 and capacity = 4\n", + "Vector: size = 5 and capacity = 8\n", + "Vector: size = 6 and capacity = 8\n", + "Vector: size = 7 and capacity = 8\n", + "Vector: size = 8 and capacity = 8\n", + "Vector: size = 9 and capacity = 16\n" + ] + } + ], "source": [ "#include <vector>\n", "#include <iostream>\n", @@ -344,16 +450,33 @@ "\n", "### `reserve()` and `resize()`\n", "\n", - "`reserve()` is the method to set manually the size of the capacity. When you have a clue of the expected number of elements, it is better to provide it: even if your guess was flawed, it limits the number of reallocations:\n", + "`reserve()` is the method to set manually the value of the capacity. When you have a clue of the expected number of elements, it is better to provide it: even if your guess was flawed, it limits the number of reallocations:\n", "\n", "\n" ] }, { "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Vector: size = 0 and capacity = 5\n", + "Vector: size = 1 and capacity = 5\n", + "Vector: size = 2 and capacity = 5\n", + "Vector: size = 3 and capacity = 5\n", + "Vector: size = 4 and capacity = 5\n", + "Vector: size = 5 and capacity = 5\n", + "Vector: size = 6 and capacity = 10\n", + "Vector: size = 7 and capacity = 10\n", + "Vector: size = 8 and capacity = 10\n", + "Vector: size = 9 and capacity = 10\n" + ] + } + ], "source": [ "#include <vector>\n", "#include <iostream>\n", @@ -380,7 +503,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 14, "metadata": {}, "outputs": [], "source": [ @@ -420,9 +543,19 @@ }, { "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], + "execution_count": 15, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Size = 2 Capacity = 2 Content = [3, 5]\n", + "Size = 8 Capacity = 8 Content = [3, 5, 10, 10, 10, 10, 10, 10]\n", + "Size = 3 Capacity = 8 Content = [3, 5, 10]\n" + ] + } + ], "source": [ "#include <vector>\n", "#include <iostream>\n", @@ -449,9 +582,20 @@ }, { "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], + "execution_count": 16, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Size = 2 Capacity = 2 Content = [3, 5]\n", + "Size = 8 Capacity = 8 Content = [3, 5, 10, 10, 10, 10, 10, 10]\n", + "Size = 3 Capacity = 8 Content = [3, 5, 10]\n", + "Size = 3 Capacity = 3 Content = [3, 5, 10]\n" + ] + } + ], "source": [ "#include <vector>\n", "#include <iostream>\n", @@ -484,9 +628,26 @@ }, { "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], + "execution_count": 17, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Digit = 0\n", + "Digit = 0\n", + "Digit = 0\n", + "Digit = 0\n", + "Digit = 0\n", + "Digit = 3\n", + "Digit = 1\n", + "Digit = 4\n", + "Digit = 1\n", + "Digit = 5\n" + ] + } + ], "source": [ "#include <vector>\n", "#include <iostream>\n", @@ -518,7 +679,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 18, "metadata": {}, "outputs": [], "source": [ @@ -542,7 +703,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 19, "metadata": {}, "outputs": [], "source": [ @@ -591,9 +752,17 @@ }, { "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], + "execution_count": 20, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "3 8 9 -12.3 -32.35 " + ] + } + ], "source": [ "#include <vector>\n", "#include <iostream>\n", @@ -611,15 +780,23 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "It is not extremely efficient: at each call to `operator[]`, the program must figure out the element to draw without using the fact it had just fetched the element just in the previous memory location. Iterators provides this more efficient access:\n", + "It may not extremely efficient: at each call to `operator[]`, the program must figure out the element to draw without using the fact it had just fetched the element just in the previous memory location (in practice now compilers are rather smart and figure this out...) Iterators provides this more efficient access:\n", "\n" ] }, { "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], + "execution_count": 21, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0\t3 1\t8 2\t9 3\t-12.3 4\t-32.35 " + ] + } + ], "source": [ "#include <vector>\n", "#include <iostream>\n", @@ -644,7 +821,7 @@ "There are several flavors:\n", "* Constant iterators, used here, with which you can only read the value under the iterator.\n", "* Iterators, with which you can also modify it.\n", - "* Reverse iterators, to iterate the container from the last to the first.\n", + "* Reverse iterators, to iterate the container from the last to the first (avoid them if you can: they are a bit messy to use and may not be used in every algorithms in which standard iterators are ok...)\n", "\n", "There are default values for each container:\n", "\n", @@ -660,9 +837,17 @@ }, { "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], + "execution_count": 22, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Size = 9 Capacity = 12 Content = [2, 3, 4, 5, 7, 18, 4, 6, 20]\n" + ] + } + ], "source": [ "#include <vector>\n", "\n", @@ -694,9 +879,18 @@ }, { "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], + "execution_count": 23, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "3 8 9 -12.3 -32.35 \n", + "3 8 9 -12.3 -32.35 " + ] + } + ], "source": [ "#include <vector>\n", "#include <iostream>\n", @@ -735,9 +929,9 @@ "\n", "`std::vector` is not the only possible choice; I will present very briefly the other possibilities here:\n", "\n", - "* `std::list`: A double-linked list: the idea is that each element knows the address of the element before and the element after. It might be considered if you need to add often elements at specific locations in the list: adding a new element is just changing 2 pointers and setting 2 new ones for instances. You can't access directly an element by its index with a `std::list`.\n", + "* `std::list`: A double-linked list: the idea is that each element knows the addresses of the element before and the element after. It might be considered if you need to add often elements at specific locations in the list: adding a new element is just changing 2 pointers and setting 2 new ones. You can't access directly an element by its index with a `std::list`.\n", "* `std::slist`: A single-linked list: similar as a `std::list` except only the pointer to the next element is kept.\n", - "* `std::deque`: For \"double ended queue\"; this container may be helpful if you need to store a really huge amount of data that might not fit within a `std::vector`. It might also be of use if you are to add often elements in front on the list: there is `push_front()` method as well as a `push_back` one. Item 18 of \\cite{Meyers2001} recommends using `std::deque` with `bool`: `std::vector<bool>` was an experiment to provide a specific implementation to spare memory that went wrong...\n", + "* `std::deque`: For \"double ended queue\"; this container may be helpful if you need to store a really huge amount of data that might not fit within a `std::vector`. It might also be of use if you are to add often elements in front on the list: there is `push_front()` method as well as a `push_back` one. Item 18 of \\cite{Meyers2001} recommends using `std::deque` with `bool`: `std::vector<bool>` was an experiment to provide a specific implementation to spare memory that went wrong and should therefore be avoided...\n", "* `std::array`: You should use this one if the number of elements is known at compile time and doesn't change at all.\n", "* `std::string`: Yes, it is actually a container! I will not tell much more about it; just add that it is the sole container besides `std::vector` that ensures continuous storage.\n", "\n", @@ -759,7 +953,7 @@ "metadata": {}, "source": [ "\n", - "© _CNRS 2016_ - _Inria 2018-2019_ \n", + "© _CNRS 2016_ - _Inria 2018-2020_ \n", "_This notebook is an adaptation of a lecture prepared by David Chamont (CNRS) under the terms of the licence [Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0)](http://creativecommons.org/licenses/by-nc-sa/4.0/)_ \n", "_The present version has been written by Sébastien Gilles and Vincent Rouvreau (Inria)_" ] @@ -769,14 +963,14 @@ "kernelspec": { "display_name": "C++17", "language": "C++17", - "name": "xeus-cling-cpp17" + "name": "xcpp17" }, "language_info": { "codemirror_mode": "text/x-c++src", "file_extension": ".cpp", "mimetype": "text/x-c++src", "name": "c++", - "version": "-std=c++17" + "version": "17" }, "latex_envs": { "LaTeX_envs_menu_present": true, diff --git a/5-UsefulConceptsAndSTL/4-AssociativeContainers.ipynb b/5-UsefulConceptsAndSTL/4-AssociativeContainers.ipynb index f794cd80c46485ac7d4ddee9a5df7ea0cb323883..a94741dcd522ebf38e44db41d7b5508b772bbd21 100644 --- a/5-UsefulConceptsAndSTL/4-AssociativeContainers.ipynb +++ b/5-UsefulConceptsAndSTL/4-AssociativeContainers.ipynb @@ -4,7 +4,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "# [Getting started in C++](/) - [Useful concepts and STL](/notebooks/5-UsefulConceptsAndSTL/0-main.ipynb) - [Associative containers](/notebooks/5-UsefulConceptsAndSTL/4-AssociativeContainers.ipynb)" + "# [Getting started in C++](/) - [Useful concepts and STL](./0-main.ipynb) - [Associative containers](./4-AssociativeContainers.ipynb)" ] }, { @@ -243,7 +243,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "That's somewhere I dislike in this very useful class: error handling is not up to my taste... \n", + "That's something I dislike in this very useful class: error handling is not up to my taste as you have to remember to check explicitly all went right...\n", "\n", "### Access to one element: don't use `operator[]`!\n", "\n", @@ -279,9 +279,9 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "So if you provide a wrong key; it doesn't yell and create on the spot a new entry, filling the associated value with the default constructor for the type...\n", + "So if you provide a wrong key, it doesn't yell and create on the spot a new entry, filling the associated value with the default constructor for the type...\n", "\n", - "To do it properly (but more verbose!), use the `find()` method (if you're intrigued by the use of iterator there, we will present them more in details in the notebook about [algorithms](/notebooks/5-UsefulConceptsAndSTL/7-Algorithms.ipynb)):" + "To do it properly (but more verbose!), use the `find()` method (if you're intrigued by the use of iterator there, we will present them more in details in the notebook about [algorithms](./7-Algorithms.ipynb)):" ] }, { @@ -411,7 +411,7 @@ "metadata": {}, "source": [ "\n", - "© _CNRS 2016_ - _Inria 2018-2019_ \n", + "© _CNRS 2016_ - _Inria 2018-2020_ \n", "_This notebook is an adaptation of a lecture prepared by David Chamont (CNRS) under the terms of the licence [Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0)](http://creativecommons.org/licenses/by-nc-sa/4.0/)_ \n", "_The present version has been written by Sébastien Gilles and Vincent Rouvreau (Inria)_" ] @@ -421,14 +421,14 @@ "kernelspec": { "display_name": "C++17", "language": "C++17", - "name": "xeus-cling-cpp17" + "name": "xcpp17" }, "language_info": { "codemirror_mode": "text/x-c++src", "file_extension": ".cpp", "mimetype": "text/x-c++src", "name": "c++", - "version": "-std=c++17" + "version": "17" }, "latex_envs": { "LaTeX_envs_menu_present": true, diff --git a/5-UsefulConceptsAndSTL/5-MoveSemantics.ipynb b/5-UsefulConceptsAndSTL/5-MoveSemantics.ipynb index a651b437c7b5745eba28984dccf99ac29df1be47..6de5de5546edf465cd51e6281393755a9dff3177 100644 --- a/5-UsefulConceptsAndSTL/5-MoveSemantics.ipynb +++ b/5-UsefulConceptsAndSTL/5-MoveSemantics.ipynb @@ -4,7 +4,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "# [Getting started in C++](/) - [Useful concepts and STL](/notebooks/5-UsefulConceptsAndSTL/0-main.ipynb) - [Move semantics](/notebooks/5-UsefulConceptsAndSTL/5-MoveSemantics.ipynb)" + "# [Getting started in C++](/) - [Useful concepts and STL](./0-main.ipynb) - [Move semantics](./5-MoveSemantics.ipynb)" ] }, { @@ -297,7 +297,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Noteworthy exception: a reference \"constant\" (language abuse designating a reference to a constant value) can be attached to a temporary value, in particular to facilitate implicit conversions:" + "Noteworthy exception: a \"constant\" reference (language abuse designating a reference to a constant value) can be attached to a temporary value, in particular to facilitate implicit conversions:" ] }, { @@ -821,7 +821,7 @@ "source": [ "With all this move semantics, the operations above are comparable to what we achieved with the `swap` function for `Text` earlier... with the additional benefit that this semantic is not only used for swapping two values.\n", "\n", - "As already mentioned [there](/notebooks/3-Operators/4-CanonicalForm.ipynb#[Advanced]-The-true-canonical-class), there are specific rules called __Rule of 0__, __Rule of 3__ and __Rule of 5__, which explains which constructor(s), destructor and assigmnent operator you ought to define for your class.\n", + "As already mentioned [there](../3-Operators/4-CanonicalForm.ipynb#[Advanced]-The-true-canonical-class), there are specific rules called __Rule of 0__, __Rule of 3__ and __Rule of 5__, which explains which constructor(s), destructor and assigmnent operator you ought to define for your class.\n", "\n", "\n", "## Temporary reference argument within a function\n", @@ -865,7 +865,7 @@ "\n", "All containers in the standard library are now enhanced with move constructors and move assignment operators.\n", "\n", - "Moreover, the move semantics is not only about improving performance. There are classes (such as `std::unique_ptr` we'll see in [next notebook](/notebooks/5-UsefulConceptsAndSTL/6-SmartPointers.ipynb#unique_ptr)) for which it makes no sense for objects to be copyable, but where it is necessary for them to be movable. In this case, the class has a constructor per move, and no constructor per copy.\n", + "Moreover, the move semantics is not only about improving performance. There are classes (such as `std::unique_ptr` we'll see in [next notebook](./6-SmartPointers.ipynb#unique_ptr)) for which it makes no sense for objects to be copyable, but where it is necessary for them to be movable. In this case, the class has a constructor per move, and no constructor per copy.\n", "\n", "An object that has been \"emptied\" as a result of a move is no longer supposed to be useful for anything. However if not destroyed it is still recommended, when you implement this type of class and move, to leave the emptied object in a \"valid\" state; that's why we put in our `Text2` class the `data_` pointer to `nullptr` and the `size_` to 0. The best is of course to ensure its destruction at short notice to avoid any mishap." ] @@ -938,7 +938,7 @@ "metadata": {}, "source": [ "\n", - "© _CNRS 2016_ - _Inria 2018-2019_ \n", + "© _CNRS 2016_ - _Inria 2018-2020_ \n", "_This notebook is an adaptation of a lecture prepared by David Chamont (CNRS) under the terms of the licence [Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0)](http://creativecommons.org/licenses/by-nc-sa/4.0/)_ \n", "_The present version has been written by Sébastien Gilles and Vincent Rouvreau (Inria)_" ] @@ -948,14 +948,14 @@ "kernelspec": { "display_name": "C++17", "language": "C++17", - "name": "xeus-cling-cpp17" + "name": "xcpp17" }, "language_info": { "codemirror_mode": "text/x-c++src", "file_extension": ".cpp", "mimetype": "text/x-c++src", "name": "c++", - "version": "-std=c++17" + "version": "17" }, "latex_envs": { "LaTeX_envs_menu_present": true, diff --git a/5-UsefulConceptsAndSTL/6-SmartPointers.ipynb b/5-UsefulConceptsAndSTL/6-SmartPointers.ipynb index f9740073bdb3bf3b6592a7d5ba57b91fd98f12b6..9fc1467325136678eac11528c2ded76e64c7c8d8 100644 --- a/5-UsefulConceptsAndSTL/6-SmartPointers.ipynb +++ b/5-UsefulConceptsAndSTL/6-SmartPointers.ipynb @@ -4,7 +4,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "# [Getting started in C++](/) - [Useful concepts and STL](/notebooks/5-UsefulConceptsAndSTL/0-main.ipynb) - [Smart pointers](/notebooks/5-UsefulConceptsAndSTL/6-SmartPointers.ipynb)" + "# [Getting started in C++](/) - [Useful concepts and STL](./0-main.ipynb) - [Smart pointers](./6-SmartPointers.ipynb)" ] }, { @@ -23,9 +23,9 @@ "source": [ "## Introduction\n", "\n", - "In short, **smart pointers** are the application of [RAII](/notebooks/5-UsefulConceptsAndSTL/2-RAII.ipynb) to pointers: objects which handle more nicely the acquisition and release of dynamic allocation.\n", + "In short, **smart pointers** are the application of [RAII](./2-RAII.ipynb) to pointers: objects which handle more nicely the acquisition and release of dynamic allocation.\n", "\n", - "There are many ways to define the behaviour of a smart pointer (the dedicated chapter in \\cite{Alexandrescu2001} is a very interesting read for this, especially as it uses heavily the template [policies](/notebooks/4-Templates/5-MoreAdvanced.ipynb#Policies) to implement his):\n", + "There are many ways to define the behaviour of a smart pointer (the dedicated chapter in \\cite{Alexandrescu2001} is a very interesting read for this, especially as it uses heavily the template [policies](../4-Templates/5-MoreAdvanced.ipynb#Policies) to implement his):\n", "\n", "* How the pointer might be copied (or not).\n", "* When is the memory freed.\n", @@ -37,7 +37,7 @@ "* **unique pointers**\n", "* **shared pointers** (and the **weak** ones that goes along with them).\n", "\n", - "One should also mention for legacy the first attempt: **auto pointers**, which were removed in C++ 17: you might encounter them in some libraries, but by all means don't use them yourself (look for *sink effect* if you want to know why).\n", + "One should also mention for legacy the first attempt: **auto pointers**, which were removed in C++ 17: you might encounter them in some libraries, but by all means don't use them yourself (look for *sink effect* on the Web if you want to know why).\n", "\n", "By design all smart pointers keep the whole syntax semantic:\n", "* `*` to dereference the (now smart) pointer.\n", @@ -93,7 +93,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 1, "metadata": {}, "outputs": [], "source": [ @@ -117,9 +117,31 @@ }, { "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001b[1minput_line_10:5:10: \u001b[0m\u001b[0;1;31merror: \u001b[0m\u001b[1mcall to implicitly-deleted copy constructor of 'std::__1::unique_ptr<int, std::__1::default_delete<int> >'\u001b[0m\n", + " auto copy = ptr; // COMPILATION ERROR: can't be copied! \n", + "\u001b[0;1;32m ^ ~~~\n", + "\u001b[0m\u001b[1m/Users/Shared/Software/miniconda3/envs/formation_cpp_2020/include/c++/v1/memory:2488:3: \u001b[0m\u001b[0;1;30mnote: \u001b[0mcopy constructor is implicitly deleted because 'unique_ptr<int, std::__1::default_delete<int> >' has a user-declared move constructor\u001b[0m\n", + " unique_ptr(unique_ptr&& __u) _NOEXCEPT\n", + "\u001b[0;1;32m ^\n", + "\u001b[0m" + ] + }, + { + "ename": "Interpreter Error", + "evalue": "", + "output_type": "error", + "traceback": [ + "Interpreter Error: " + ] + } + ], "source": [ "#include <memory>\n", "\n", @@ -132,15 +154,34 @@ }, { "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001b[1minput_line_14:4:26: \u001b[0m\u001b[0;1;31merror: \u001b[0m\u001b[1mcall to implicitly-deleted copy constructor of 'std::unique_ptr<int>'\u001b[0m\n", + " std::unique_ptr<int> copy = std::move(ptr); // Ok\n", + "\u001b[0;1;32m ^ ~~~~~~~~~~~~~~\n", + "\u001b[0m" + ] + }, + { + "ename": "Interpreter Error", + "evalue": "", + "output_type": "error", + "traceback": [ + "Interpreter Error: " + ] + } + ], "source": [ "#include <memory>\n", "\n", "{\n", " std::unique_ptr<int> ptr = std::make_unique<int>(5);\n", - " auto copy = std::move(ptr); // Ok\n", + " auto copy = std::move(ptr); // Ok - or should be (recent Xeus cling doesn't concur but is wrong...)\n", "}" ] }, @@ -148,7 +189,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "As usual with move semantics, beware in this second case: ptr is undefined after the move occurred...\n", + "As usual with move semantics, beware in this second case: ptr is undefined after the `move` occurred...\n", "\n", "### Usage to store data in a class\n", "\n", @@ -372,7 +413,7 @@ "\n", "`shared_ptr` are clearly useful, but you should always wonder first if you really need them: for most uses a `unique_ptr` eventually seconded by raw pointers extracted by `get()` is enough.\n", "\n", - "There is also a risk of not releasing properly the memory is there is a circular dependancy between two `shared_ptr`. A variation of this pointer named `weak_ptr` enables to circumvent this issue, but is a bit tedious to put into motion. I have written in [appendix](/notebooks/7-Appendix/WeakPtr.ipynb) to describe how to do so.\n", + "There is also a risk of not releasing properly the memory is there is a circular dependancy between two `shared_ptr`. A variation of this pointer named `weak_ptr` enables to circumvent this issue, but is a bit tedious to put into motion. I have written in [appendix](../7-Appendix/WeakPtr.ipynb) to describe how to do so.\n", "\n" ] }, @@ -572,7 +613,7 @@ "metadata": {}, "source": [ "\n", - "© _CNRS 2016_ - _Inria 2018-2019_ \n", + "© _CNRS 2016_ - _Inria 2018-2020_ \n", "_This notebook is an adaptation of a lecture prepared by David Chamont (CNRS) under the terms of the licence [Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0)](http://creativecommons.org/licenses/by-nc-sa/4.0/)_ \n", "_The present version has been written by Sébastien Gilles and Vincent Rouvreau (Inria)_" ] @@ -582,14 +623,14 @@ "kernelspec": { "display_name": "C++17", "language": "C++17", - "name": "xeus-cling-cpp17" + "name": "xcpp17" }, "language_info": { "codemirror_mode": "text/x-c++src", "file_extension": ".cpp", "mimetype": "text/x-c++src", "name": "c++", - "version": "-std=c++17" + "version": "17" }, "latex_envs": { "LaTeX_envs_menu_present": true, diff --git a/6-InRealEnvironment/3-Compilers.ipynb b/6-InRealEnvironment/3-Compilers.ipynb index 2d9c646ca11ccf4c39e0ad55a71fcc5484641b4c..898ce38b8191918a72c11a316c93f0eed5c50647 100644 --- a/6-InRealEnvironment/3-Compilers.ipynb +++ b/6-InRealEnvironment/3-Compilers.ipynb @@ -182,14 +182,14 @@ "kernelspec": { "display_name": "C++17", "language": "C++17", - "name": "xeus-cling-cpp17" + "name": "xcpp17" }, "language_info": { "codemirror_mode": "text/x-c++src", "file_extension": ".cpp", "mimetype": "text/x-c++src", "name": "c++", - "version": "-std=c++17" + "version": "17" }, "latex_envs": { "LaTeX_envs_menu_present": true,