Right. Sometimes language features support an architectural pattern, sometimes they are just mechanism.
And sometimes the same feature is one, sometimes the other. There is no shame in it. Language features are there to be used.
And sometimes the same feature is one, sometimes the other. There is no shame in it. Language features are there to be used.
It is unfortunate that there is no explicit way to distinguish OOP is-a from code reuse, other than the presence of virtual functions in base classes, but in my 15 years of professional use of c++ I can't remember it ever being an issue.