bugs
A fancy array.
It is a surprisingly fuzzy concept.
Historically, OOP languages like C++ and Java have evolved from Simula. Simula was designed and used to simulate ships. From this comes the notion that OOP objects should be physical “things”. But this has not aged well.
Simula also had the idea to build definitions by hierarchical implementation inheritance. C++ adopted that, too, and apart from usage in GUI frameworks, this has not aged well, either.
Then there was Smalltalk, which has an entirely different concept from C++, focusing on messaging. Here, methods are messages.
The best modern explanation I’ve read is from Sandy Metz in “Practical Object Oriented Design in Ruby”.
https://hellread.com/2025/07/03/practical-object-oriented-design-in-ruby-by-sandi-metz/
https://sandimetz.com/products
What she explains is that one should group code and data so that this limits the scope of change when evolving the program.
Then, there is the much older idea that the programmer defines data types and operations on them which guarantee invariants. It is a very powerful concept, and was already described by Edsgar Dijkstra in 1970:
https://www.cs.utexas.edu/~EWD/transcriptions/EWD02xx/EWD249/EWD249.html
https://seriouscomputerist.atariverse.com/media/pdf/book/Structured Programming.pdf
C++ uses this concept, too, in its container classes, but in a bastardized form: Invariants are suggested but rarely spelled out. You can for example iterate over elements of a container class / collection, but whether the iteraror remains valid with certain operations or not, and triggers Undefined Behavior, you are not told explictely. In contrast, for Dijkstra it was essential that operations and invariants were well-defined and written out.
A blob of memory, and associated pointers to functions. And a lot of assembly magic to make it work.
Why assembly?
Does C not allow putting the v-table in static memory/text or where is the hangup?