The blueprint
A class describes a new type. Tally says what every Tally object holds, one int called n, and which functions work on it. Writing a class makes no object yet: nothing is in memory.
n is a data member. add and get are member functions: they live inside the class and work on one object's data. In a class, members are private until public: says otherwise, so n is private.
Using an object
Tally t{5}; makes an object named t. Memory for its n is set aside, then the constructor runs and sets n to 5. The object's lifetime begins when its constructor finishes.
t.add(3) calls add on the object t. Inside add, n means t's own n, so 5 becomes 8. Code outside the class can change n only through functions the class offers, like add.
t.get() reads n and hands back 8, which std::cout prints. The const after get() is a promise: this function will not change the object. The compiler holds it to that promise.
Write t.n = 9; in main and the program will not compile: n is private, so only Tally's own members may touch it. This is encapsulation: the class guards its data and decides what others may do.
Lifetime
Tally u{1}; makes a second object from the same blueprint. u has its own n, set to 1, in its own memory. Changing u never changes t. u lives inside an inner pair of braces: a smaller scope.
At the closing brace of its scope, u's life ends. C++ calls its destructor, ~Tally, by itself: it prints bye 1, then u's memory is given back. You never call it yourself for objects like u.
At the end of main, t goes out of scope too, and its destructor prints bye 8. Local objects are destroyed in reverse order of construction: u, made last, went first; t, made first, goes last.
The constructor runs when an object is made; the destructor runs when its scope ends, even after an early return or a caught exception. Tie a resource, like an open file, to an object and it is released on its own. That is RAII.
What happens
;; step 1/10 · blueprint
tally.cpp (one file; it starts with #include <iostream>)
1 class Tally {
2 int n;
3 public:
4 Tally(int s) : n{s} {}
5 void add(int k) { n += k; }
6 int get() const { return n; }
7 ~Tally() {
8 std::cout << "bye " << n << '\n';
9 }
10 };
a type, like int, but one you designed
no object exists yet: nothing in memory
The two cards are one file, tally.cpp, which starts with #include <iostream>. Build it with g++ -std=c++20 tally.cpp -o tally and run ./tally: it prints 8, bye 1 and bye 8 on three lines. Precisely, an object's lifetime begins when its initialization (here, the constructor) is complete and ends when its destructor call starts. Objects with automatic storage duration, like t and u, are destroyed at the end of the block they were made in, in reverse order of construction.