"* Should get a constructor which sets the resolution.\n",
"* Should get a constructor which sets the resolution (known as `maximum_error_index` in the previous exercice).\n",
"* Includes a protected method named `PrintLine()` that will replace the `print_line()` we introduced in previous exercice.\n",
"* Includes a protected method named `PrintLine()` that will replace the `print_line()` we introduced in previous exercice.\n",
"\n",
"\n",
"The constructors of derived classes will of course have to be modified accordingly: so far we relied on default ones."
"The constructors of derived classes will of course have to be modified accordingly: so far we relied on default ones."
...
@@ -311,14 +311,14 @@
...
@@ -311,14 +311,14 @@
"kernelspec": {
"kernelspec": {
"display_name": "C++17",
"display_name": "C++17",
"language": "C++17",
"language": "C++17",
"name": "xeus-cling-cpp17"
"name": "xcpp17"
},
},
"language_info": {
"language_info": {
"codemirror_mode": "text/x-c++src",
"codemirror_mode": "text/x-c++src",
"file_extension": ".cpp",
"file_extension": ".cpp",
"mimetype": "text/x-c++src",
"mimetype": "text/x-c++src",
"name": "c++",
"name": "c++",
"version": "-std=c++17"
"version": "17"
},
},
"latex_envs": {
"latex_envs": {
"LaTeX_envs_menu_present": true,
"LaTeX_envs_menu_present": true,
...
...
%% Cell type:markdown id: tags:
%% Cell type:markdown id: tags:
# [Getting started in C++](/) - [Object programming](/notebooks/2-ObjectProgramming/0-main.ipynb) - [TP 8](/notebooks/2-ObjectProgramming/6b-TP.ipynb)
# [Getting started in C++](/) - [Object programming](/notebooks/2-ObjectProgramming/0-main.ipynb) - [TP 8](/notebooks/2-ObjectProgramming/6b-TP.ipynb)
%% Cell type:markdown id: tags:
%% Cell type:markdown id: tags:
<h1>Table of contents<spanclass="tocSkip"></span></h1>
<h1>Table of contents<spanclass="tocSkip"></span></h1>
<divclass="toc"><ulclass="toc-item"><li><span><ahref="#EXERCICE-21:-base-class-TestDisplay"data-toc-modified-id="EXERCICE-21:-base-class-TestDisplay-1">EXERCICE 21: base class <code>TestDisplay</code></a></span></li><li><span><ahref="#EXERCICE-22:-inherit-from-TestDisplayPowerOfTwoApprox"data-toc-modified-id="EXERCICE-22:-inherit-from-TestDisplayPowerOfTwoApprox-2">EXERCICE 22: inherit from <code>TestDisplayPowerOfTwoApprox</code></a></span></li><li><span><ahref="#EXERCICE-23:-Toward-a-TestDisplayContainer-class"data-toc-modified-id="EXERCICE-23:-Toward-a-TestDisplayContainer-class-3">EXERCICE 23: Toward a <code>TestDisplayContainer</code> class</a></span></li><li><span><ahref="#EXERCICE-24:-dynamic-allocation-of-array"data-toc-modified-id="EXERCICE-24:-dynamic-allocation-of-array-4">EXERCICE 24: dynamic allocation of array</a></span></li><li><span><ahref="#EXERCICE-25:-transform-TestDisplayContainer::Do()-into-a-free-function"data-toc-modified-id="EXERCICE-25:-transform-TestDisplayContainer::Do()-into-a-free-function-5">EXERCICE 25: transform <code>TestDisplayContainer::Do()</code> into a free function</a></span></li></ul></div>
<divclass="toc"><ulclass="toc-item"><li><span><ahref="#EXERCICE-21:-base-class-TestDisplay"data-toc-modified-id="EXERCICE-21:-base-class-TestDisplay-1">EXERCICE 21: base class <code>TestDisplay</code></a></span></li><li><span><ahref="#EXERCICE-22:-inherit-from-TestDisplayPowerOfTwoApprox"data-toc-modified-id="EXERCICE-22:-inherit-from-TestDisplayPowerOfTwoApprox-2">EXERCICE 22: inherit from <code>TestDisplayPowerOfTwoApprox</code></a></span></li><li><span><ahref="#EXERCICE-23:-Toward-a-TestDisplayContainer-class"data-toc-modified-id="EXERCICE-23:-Toward-a-TestDisplayContainer-class-3">EXERCICE 23: Toward a <code>TestDisplayContainer</code> class</a></span></li><li><span><ahref="#EXERCICE-24:-dynamic-allocation-of-array"data-toc-modified-id="EXERCICE-24:-dynamic-allocation-of-array-4">EXERCICE 24: dynamic allocation of array</a></span></li><li><span><ahref="#EXERCICE-25:-transform-TestDisplayContainer::Do()-into-a-free-function"data-toc-modified-id="EXERCICE-25:-transform-TestDisplayContainer::Do()-into-a-free-function-5">EXERCICE 25: transform <code>TestDisplayContainer::Do()</code> into a free function</a></span></li></ul></div>
%% Cell type:markdown id: tags:
%% Cell type:markdown id: tags:
### EXERCICE 21: base class `TestDisplay`
### EXERCICE 21: base class `TestDisplay`
Create a base class `TestDisplay` from which both `TestDisplayPowerOfTwoApprox` and `TestDisplaySum` will inherit publicly.
Create a base class `TestDisplay` from which both `TestDisplayPowerOfTwoApprox` and `TestDisplaySum` will inherit publicly.
This class:
This class:
* Should get a constructor which sets the resolution.
* Should get a constructor which sets the resolution (known as `maximum_error_index` in the previous exercice).
* Includes a protected method named `PrintLine()` that will replace the `print_line()` we introduced in previous exercice.
* Includes a protected method named `PrintLine()` that will replace the `print_line()` we introduced in previous exercice.
The constructors of derived classes will of course have to be modified accordingly: so far we relied on default ones.
The constructors of derived classes will of course have to be modified accordingly: so far we relied on default ones.
%% Cell type:markdown id: tags:
%% Cell type:markdown id: tags:
### EXERCICE 22: inherit from `TestDisplayPowerOfTwoApprox`
### EXERCICE 22: inherit from `TestDisplayPowerOfTwoApprox`
We would like to get back former output in which we got first all outputs for 0.65, then all the ones for 0.35.
We would like to get back former output in which we got first all outputs for 0.65, then all the ones for 0.35.
To do so, we will create two classes `TestDisplayPowerOfTwoApprox065` and `TestDisplayPowerOfTwoApprox035` that inherits from `TestDisplayPowerOfTwoApprox`.
To do so, we will create two classes `TestDisplayPowerOfTwoApprox065` and `TestDisplayPowerOfTwoApprox035` that inherits from `TestDisplayPowerOfTwoApprox`.
Of course, we still abide by the DRY principle and we want to specialize only the code related to `Do()` method.
Of course, we still abide by the DRY principle and we want to specialize only the code related to `Do()` method.
The `main()` to use:
The `main()` to use:
%% Cell type:code id: tags:
%% Cell type:code id: tags:
``` C++17
``` C++17
int main(int argc, char** argv)
int main(int argc, char** argv)
{
{
static_cast<void>(argc); // to silence warning about unused argc - don't bother
static_cast<void>(argc); // to silence warning about unused argc - don't bother
static_cast<void>(argv); // to silence warning about unused argv - don't bother
static_cast<void>(argv); // to silence warning about unused argv - don't bother
Instead of setting an arbitrary size of 3, we will now add a size dynamically in `TestDisplayContainer` constructor; the internal storage will now be:
Instead of setting an arbitrary size of 3, we will now add a size dynamically in `TestDisplayContainer` constructor; the internal storage will now be:
````
````
TestDisplay** test_display_list_;
TestDisplay** test_display_list_;
````
````
meaning we will store an array of pointers (don't worry, we will see later how to avoid such monstruosities... but it is useful nonetheless to try them a bit).
meaning we will store an array of pointers (don't worry, we will see later how to avoid such monstruosities... but it is useful nonetheless to try them a bit).
Constructor must now:
Constructor must now:
* Allocate the array of `TestDisplay*` with a **capacity** given as its argument (the capacity being the number of elements that *might* be stored inside - we'll see the chosen name is not a whim).
* Allocate the array of `TestDisplay*` with a **capacity** given as its argument (the capacity being the number of elements that *might* be stored inside - we'll see the chosen name is not a whim).
* Keep track of the capacity (the related data attribute should be constant: we don't intend to modify the capacity of the array after construction).
* Keep track of the capacity (the related data attribute should be constant: we don't intend to modify the capacity of the array after construction).
* Set each element to `nullptr`.
* Set each element to `nullptr`.
Destructor must of course take care of deallocating properly the memory.
Destructor must of course take care of deallocating properly the memory.
**NOTE:** To avoid a warning you should use `std::size_t` when allocating the array: this is the type used for array (which is in all compilers I've used an alias to `unsigned long` but standard dictates you should use `std::size_t`).
**NOTE:** To avoid a warning you should use `std::size_t` when allocating the array: this is the type used for array (which is in all compilers I've used an alias to `unsigned long` but standard dictates you should use `std::size_t`).
%% Cell type:markdown id: tags:
%% Cell type:markdown id: tags:
### EXERCICE 25: transform `TestDisplayContainer::Do()` into a free function
### EXERCICE 25: transform `TestDisplayContainer::Do()` into a free function
We probably went a bridge too far: it is useful to provide an object which contains several `TestDisplay` together, but making it take in charge the loop might not be that good an idea (in a real program you might for instance interact with this container by another mean than the pre-defined loop).
We probably went a bridge too far: it is useful to provide an object which contains several `TestDisplay` together, but making it take in charge the loop might not be that good an idea (in a real program you might for instance interact with this container by another mean than the pre-defined loop).
Replace the `Do()` method by a free function with signature:
Replace the `Do()` method by a free function with signature:
````
````
void loop(int initial_Nbit, int final_Nbit, int increment_Nbit, const TestDisplayContainer& container)
void loop(int initial_Nbit, int final_Nbit, int increment_Nbit, const TestDisplayContainer& container)
````
````
To do so, you will need to add several methods to `TestDisplayContainer`:
To do so, you will need to add several methods to `TestDisplayContainer`:
- A method that returns the **size** (i.e. the number of non nullptr `TestDisplay*` stored), which will be required to loop over the relevant elements.
- A method that returns the **size** (i.e. the number of non nullptr `TestDisplay*` stored), which will be required to loop over the relevant elements.
- A method to access the `i`-th element stored in the table. Signature might be:
- A method to access the `i`-th element stored in the table. Signature might be:
_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/)_
_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/)_
_The present version has been written by Sébastien Gilles and Vincent Rouvreau (Inria)_
_The present version has been written by Sébastien Gilles and Vincent Rouvreau (Inria)_