License : Creative Commons Attribution 4.0 International (CC BY-NC-SA 4.0)
Copyright :
Hervé Frezza-Buet,
CentraleSupelec
Last modified : April 9, 2024 11:25
Link to the source : block.md
This labwork focuses on the power of inheritance in the software design. Here, we adress the problem of writing formulas in text mode.
The following math formula
can be written as the following text
/ / x + 1 \
| |---------- + 3| * (2x + 1)
| \ x - 2001 /
| ----------------------------- = 5
| 3x + 2
<
|
| x + 5
| 2x + ------- = 12
\ x + 8
The difficuty is to write this text line by line, since, for example, one of these lines is (we use .
to represent spaces for the sake of illustration)
.|...\.x.-.2001...../................
A smart solution is to use inheritance. We will not set up a grid of characters in which we will draw the formulas. Rather, we will as every drawable stuff to be able to print one of its line. Such drawable thing will be called a block.
So printing a block on the terminal consists of asking it to print its lines one after the others.
We will give a number to each line of a block. One of this line, called the reference line will have number 0. The lines above the reference line have negative numbers, while the lines below will have positive numbers. For example, the line numbers of our formula could be
-5: / / x + 1 \
-4: | |---------- + 3| * (2x + 1)
-3: | \ x - 2001 /
-2: | ----------------------------- = 5
-1: | 3x + 2
0: <
1: |
2: | x + 5
3: | 2x + ------- = 12
4: \ x + 8
We will print line numbers in this labwork, for the sake of illustration (and debugging). So when we ask this block to print its line number -3
, it prints (spaces are represented by dots).
-3: .|...\.x.-.2001...../................
Saying that a block, whatever it is, is something that knows hos to print each of its lines, is an approach that has an inheritence flavor… this is what this labork will exploit.
Download the blocks.tar.gz archive. It contains numbered test files. Hereafter, you will be asked to fill blk*.cpp
, sometimes blk*.hpp
files as well (the file blk.hpp
includes all of them at once), and make sure that the test file corresponding to the question you are addressing compiles and runs fine.
For example, compiling and running the first test is done by
mylogin@mymachine:~$ g++ -o test -I. -std=c++17 -pedantic -Wall blk*.cpp test-001-debug.cpp
mylogin@mymachine:~$ ./test
You can find the solutions in the blocks-solution.tar.gz archive, but you are really encouraged not to use it. Making errors, and understanding why, is the way to learn C++. Ask the teachers if you get stucked.
A block is defined by its width and height, but also by the position of a reference point.
Let us start by the implementation of a block for debugging. Read the blockBlock.hpp
and the blockDebug.hpp
files and fill the blockBlock.cpp
and the blockDebug.cpp
files in order to have test test-001-debug.cpp
work correctly.
All the formulas rendering is based on 3 kinds of manipulations. They consist in building a block from one, or two other blocks. A manipulator block holds a reference to the block (or the two blocks) it handles, this is why we use share pointers. Indeed, a block can be handled by more than one manipulator.
We define 3 manipulators. The first two, beside
and over
handle two blocks. They build up a block that displays the two blocks handled, horizontally and vertically. Note the use of reference point that define how the blocks are aligned in both case, and note where is the reference point of the manipulator block.
Last manipulator is unary. It handles a single block, but behaves as if the reference point of that block were elsewhere. It is the move_ref
manipulator. The change of reference point enables to control how blocks are aligned, if the default behavior of over
and beside
is not suitable.
Read the blkBeside.hpp
file. Implement blkBeside.cpp
in order to have test test-002-001-beside.cpp
work correctly. Use the following figure to implement the computation of sizes and references.
Read the blkOver.hpp
file. Implement the blkOver.hpp
and blkOver.cpp
files in order to have test test-002-002-over.cpp
work correctly. Use the following figure to implement the computation of sizes and references.
Read the blkMoveRef.hpp
file. Implement the blkMoveRef.hpp
and blkMoveRef.cpp
files in order to have test test-002-003-moveref.cpp
work correctly. No computation hint here… this is surprisingly easy.
Write the blkText.hpp
and blkText.cpp
files in order toimplement textual blocks. Make test-003-text.cpp
compile and work fine.
Write the blkOperators.hpp
and blkOperators.cpp
files in order to implement basic operators. Make test-004-operators.cpp
compile and work fine.
There is no need for new class definitions here, only apply what we have already defined.