Welcome to the lesson on class composition in C++. You have now learned the basics of classes, methods, constructors, and encapsulation. Today, we are going to take a step further into object-oriented programming by exploring class composition. The goal of this lesson is to understand how to construct complex classes by combining simpler, reusable components.
Class composition is an essential design principle that enables you to create complex objects. We will learn how to build classes containing other objects and see practical applications of this approach. Let's get started!
What is Composition? A real-life analogy would be a car. A car comprises various parts, such as an engine, wheels, and a transmission. These parts work together to make the car function. Similarly, in programming, composition allows you to build a Car
class that includes an Engine
class, a Wheel
class, and so on.
Let's start with a simple example to understand class composition:
C++1#include <iostream> 2 3class Engine { 4public: 5 void start() { 6 std::cout << "Engine started"; 7 } 8}; 9 10class Car { 11private: 12 Engine engine; // Car has an Engine 13public: 14 void start() { 15 engine.start(); // Start the engine first 16 std::cout << " Car started"; 17 } 18}; 19 20int main() { 21 Car myCar; 22 myCar.start(); // Outputs: Engine started Car started 23 return 0; 24}
In this example, the Car
class contains an Engine
object. Here's what's happening:
Engine
class has a method called start()
, which prints "Engine started".Car
class has a private data member engine
of type Engine
.Car
class also has a start()
method that calls the Engine
's start()
method before printing "Car started".When you create a Car
object and call its start()
method, it first starts the engine and then starts the car, showing how the Car
uses functionality provided by the Engine
.
Now let's look at a more advanced example, where a Car
is composed of both Engine
and Wheel
objects:
C++1#include <iostream> 2 3class Engine { 4private: 5 int horsepower; // Engine has a horsepower attribute 6public: 7 Engine(int hp) : horsepower(hp) {} // Constructor initializes horsepower 8 int getHorsepower() const { 9 return horsepower; 10 } 11}; 12 13class Wheel { 14private: 15 int size; // Wheel has a size attribute 16public: 17 Wheel(int s) : size(s) {} // Constructor initializes size 18 int getSize() const { 19 return size; 20 } 21};
In this example, the Car
class will have both Engine
and Wheel
objects. Here are some key points:
Engine
class has a private attribute horsepower
and a method getHorsepower()
to retrieve it.Wheel
class has a private attribute size
and a method getSize()
to retrieve it.Continuing from the previous snippet, we now construct the Car
class:
C++1class Car { 2private: 3 Engine engine; 4 Wheel wheels[4]; // Composition with multiple instances of a component 5public: 6 // Constructor initializes Engine and Wheel objects 7 Car(int hp, int ws) : engine(hp), wheels{Wheel(ws), Wheel(ws), Wheel(ws), Wheel(ws)} {} 8 9 void displaySpecifications() const { 10 std::cout << "Engine: " << engine.getHorsepower() << " HP\n"; 11 std::cout << "Wheel size: " << wheels[0].getSize() << " inches\n"; 12 } 13}; 14 15int main() { 16 Car myCar(300, 18); 17 myCar.displaySpecifications(); // Outputs: Engine: 300 HP \n Wheel size: 18 inches 18 return 0; 19}
In this example:
Car
class contains an Engine
object and an array of four Wheel
objects.Car
class initializes the Engine
and Wheel
objects.displaySpecifications()
method in the Car
class prints the engine horsepower and wheel size.This approach shows how you can aggregate multiple simpler objects to build a complex object like a Car
that consists of an Engine
and multiple Wheels
.
There are several advantages to using class composition:
Using our car example, suppose you want to upgrade the car's engine or change the wheel size. With composition, you can make these changes without affecting the other parts of the car.
In this lesson, we explored the concept of class composition in C++. We learned how to combine simple classes to create complex ones, as demonstrated with our Car
, Engine
, and Wheel
examples. Composition helps in building maintainable, flexible, and reusable code by allowing the construction of complex objects from simpler components.
Next, you will move to the practice section where you will have the opportunity to apply what you've learned by creating your own classes and composing them. This hands-on experience will solidify your understanding and help you become more proficient in using composition in your programming projects. Happy coding!