When Stroustrup is talking about invariants, he is not in the first place talking about the rules that apply to the real world objects that our data structures represent, but about the rules that are required to safeguard your design.
For instance, if you have a flat array of objects, that should be kept sorted because your class assumes the list is sorted when doing binary search lookups, the fact that the list is sorted is an invariant that is logically guarded by the class.
In order to make sure your class will always work correctly, you can make sure nobody outside the class has direct access to the list, and that inserts/removals keep the list sorted.
If you make a struct in C++, by default all fields are exposed as public. If you have constraints on how the fields are modified, such a struct can be sabotaged: For instance, a struct that has a pointer to a refcounted object, should not expose it's pointer field to the outside: Users of such structs could set the pointer to null without decreasing it's refcount, or vice versa, causing memory leaks or corrupted memory.
A lot of time, I choose invariants for my own convenience: For instance, I might choose that a View
always has non-null pointer to a valid Model
. I can ensure this by preventing that the Model
property on the view can not be removed from the outside, and I add a check to the constructor that the Model
passed in is non-null, and I throw an exception otherwise. Then I can be sure that I always have a valid Model
in my View
, so I never need to handle the case that the Model
pointer in the view is null
.
Back to your example: Invariants can be thought of as assumptions that the code depends on elsewhere. So if your calculations assume a non-negative mass, you can guard this requirement by not letting users of your object class set the mass directly, and check all values passed in.
It could very well be that your code will happily work with negative mass objects, except that they will behave weirdly. Then guarding this aspect at the object level may not add any real value, so you could consider leaving it out.