In GCed languages the default seems to be that every object is referred to by pointer. Java took the "ugly" step of adding in primitive types so you could calculate 1 + 1 without causing dozens of cache misses. Struct types take this hack a step further. It generally makes the definition of the languages virtual machine a lot uglier, for example most jvm instructions operate on primitive types.
As a C++-lander, I find it surprising that object allocation is tied to the object's type. IMO, the boxed/unboxed axis should be orthogonal to the type itself. It should be a property of the object instance, not of the object's type.
An OO GC'd language "class" is a mechanism for run-time polymorphism. That's what it's for.
C++ has no "runtime" concerns of these kinds, so virtualization sits on top systems with compile-time semantics (ie., c++ classes).
If the GC language properly supported interior pointers (and first class pointers) for the GC there wouldn't be a need to force boxing in all cases. You would be able to make the decision at the point of instantiation of the object. It would make the GC more complex, but I think these days most GCs support interior pointers for other reason anyway, right?
Or am I missing something?
I feel like this is every wart in the C++ language!
Structs are just that data stored in the same layout.
Classes are just a vtable pointer to some object on heap.
Not in C++.