Should I create a reference field or a third content type to represent a many-to-many relationship?
I know you won't like this answer but in general it depends:

What are your use cases when adding a new relationship? Is it more likely to add classes via students or the other way around? Or is it a migration process?

If UI is heavily used by both of the entites, I would give reference fields to both content types, and always update the other type reference field upon saving one type.

If this is more like for listing stuff (without editing on the UI these properties) and the information is coming from a big relationship list, then I would store it in a key-value table or a custom table.