Introduction into C++ (Part 3)
C++ OOP Mastery: The Power of Composition (Has-A)
In software architecture, there are two primary ways to connect objects: Inheritance (Is-A) and Composition (Has-A). While beginners often try to solve everything through inheritance ("An Oscillator is an Envelope"), professionals prefer composition: "A Synthesizer has an Envelope."
1. Why Composition?
Think of our synthesizer as a modular rack. Each module (Oscillator, Envelope) is an independent class. The SynthEngine acts
as the chassis where these modules are plugged in.
Modularity: We can update the Envelope logic without touching a single line of the Oscillator code.
State Separation: The Envelope manages its own complex states (Attack, Decay, Sustain, Release). The Engine doesn’t care how the volume is calculated; it only cares about the result.
Reusability: We could easily add a second or third Envelope for different parameters later because the class is a self-contained unit.
2. The Signal Chain
Through composition, we build a "Signal Chain." Even in this basic version, data flows in a specific order:
Oscillator → Generates the raw, continuous audio samples.
Envelope → Acts as a "Gate," multiplying those samples by a volume level (0.0 to 1.0) based on how long a key has been held.
3. Full Reference Code (Basic Composition)
Below is the complete integrated code demonstrating the relationship between the Engine, the polymorphic Oscillator, and the ADSR Envelope.
| |
| |
| |
| |
We compile the file with a simple
1
g++ -o synth main.cpp_01 Oscillator.cpp_01 `pkg-config --cflags --libs sdl2`
and can execute the program:
1
./synth
Now, with the envelope implemented it really sounds like a true Synthesizer!!!
4. Conclusion
By using Composition, we’ve built a system that is easy to extend. The SynthEngine manages the high-level logic and
the hardware interface, while the Envelope manages the mathematical intricacies of volume shaping.
This clean separation of concerns is what makes professional C++ applications robust. In the next chapter, we will add a Voltage Controlled Filter (VCF) to this chain using this exact same compositional approach!