So, if a Tank is composed of a Vehicle and a Cannon, is a Tank a Vehicle that has a Cannon, or is it a Cannon that has a Vehicle? Obviously the former, in this case, so lets go down to the next level.
A Vehicle is composed of a Chasis, some Wheels and an Engine. Is a Vehicle a Chasis that has Wheels and an Engine? Is it an Engine that has a Chasis and Wheels? Again, the former makes most sense, but at what point does a Chasis stop being a Vehicle? If it has no Wheels and no Engine (and so is basically a stationary frame), its hardly a Vehicle any more: "A vehicle is a mechanical means of conveyance, a carriage or transport."
So you could encode some rules into your class that ensures that a Vehicle always has an Engine and Wheels. But what if we want a Plane? A Boat? A HotAirBalloon?
LorenzoGatti has a point, that the Tank and Cannon example may not be a very good one here. In most cases having a distinct Cannon class is not necessary. For most use cases in games, you are breaking down the object into more parts than you need to.
In a typical shooter or RTS game, there are no fundamental differences between a cannon and a machine gun. Both of them are types of weapons, and they mainly differ in their range, damage inflicted, and firing rate. You do not need to have a separate MachineGun class to make a weapon that has these properties differ from a Cannon class. I would just have a Weapon class (for the lack of a better word) and the stats that distinguish one weapon from another would come from an external model/data structure.
Maybe you have a case for overriding some of the behavior by the way they can be controlled and what terrain it can move over, but you may be able to extract some of this information as well. Planes can pitch and roll, regular tanks can't. Maybe apply special movement constraints in the vehicle class, then you can make a cool futuristic hover-tank that only flies for a short time. In the end I would just have a Vehicle class that would optionally contain one or more Weapons. Most games do not care about the inner workings of wheels or a vehicle chassis. If you want to give a plane a different appearance from a boat, then supply it on the view side. Tell a Vehicle object it needs to load "airplane.obj" in a structure reserved for the visual assets of the vehicle. The same goes with collision shapes. Don't try to use specialized classes to model real life, when their behaviors are very similar in the game. Instead, make components as generic as possible and provide the differences through a view and model-like design.