Ten C++ programs written over one term, in the order they were built. They are here together rather than separately because the sequence is the point: each one adds a single idea to the one before it, from allocating memory by hand through to templates that work on any type.
Every workshop is self-contained — its own sources, its own main, its own binary — and every one builds with zero warnings under -Wall -Wextra.
git clone https://github.com/Khizarc/cpp-oop-workshops.git
cd cpp-oop-workshops
make # builds all ten, reporting errors and warnings per workshopTo run one:
cd 07-polymorphism
./07-polymorphismmake clean removes every binary.
Allocating and releasing an array of names by hand with new[] and delete[], growing it as more are added. No containers — the point is to feel what std::vector does for you.
The same allocation work, plus a reusable input module: read an integer, reject anything that is not one, and constrain it to a range. Every later workshop reads its input through this.
A hand-written string library — length, copy, compare, concatenate — and a CC class that uses it to hold a credit-card record. The first class that owns a resource, and the first to face the question of what happens when one is copied.
A container with a content name, dimensions, and a volume, which can be poured into another canister. It allocates its own name, so it needs a destructor, and it validates its own dimensions: a canister built with a bad size marks itself unusable rather than half-existing.
Multiple constructors, and operator overloading: += to deposit, ~ to display, and a bool conversion so an account can be tested for validity with if (account).
Professor deriving from Employee: constructor chaining, what a derived class may reach, and what it must supply itself.
An abstract Shape base with Line, Rectangle and LblShape deriving from it, all drawn through one loop over base-class pointers. The loop never asks what kind of shape it holds.
Marks and Transcript, where the same call produces different output depending on the runtime type — and a deliberate test of chained self-assignment (T1 = T1 = T2 = T2), which corrupts any copy-assignment operator that frees before it copies.
dynaCopy, a function template that deep-copies a dynamic array of any type, alongside the rule of three applied to a Name class.
The assignment the workshops build toward. Reads fifty film records from a delimited file, parses each into a Movie, and searches them by genre — file I/O, fixed-size records, and string matching over an array of structures.
$ ./10-movie-processor
Enter the movie genre to start the search: Sci-Fi
1- Inception [2010], PG-13, duration: 148 minutes, Rating: 8.8/10
(Action, Adventure, Sci-Fi)
2- The Matrix [1999], R, duration: 136 minutes, Rating: 8.7/10
(Action, Sci-Fi)
These were written to be submitted once and never run again. Bringing all ten to a clean build turned up four real problems.
04-canister did not compile at all. Its main.cpp had been saved mid-statement — the last line ends at & with no argument, no closing call, and no return. showCans was declared at the top of the file and never defined anywhere, so even with the syntax repaired it would not have linked. The statement is completed and the function written; it also now prints a newline after each canister, which display() does not emit itself.
02-dma-and-input looped forever at end of input. getInt cleared the fail bit and retried, which never terminates once cin hits EOF — a piped run produced 2.8 million lines of prompts before it was killed. It now detects end of input and exits.
10-movie-processor had no data. It opens movies.dat and requires exactly fifty records, and the file was never kept. A fifty-film file in the format the parser expects — Title (Year)Rating|Duration|Genres|ConsumerRating — is included, so the search runs.
08-virtual-methods warned on its own test. The chained self-assignment is deliberate and worth keeping, so the warning is suppressed locally with a comment explaining why rather than by deleting the test.
MIT — see LICENSE.