In C++, I can define an accessor member function that returns the value of (or reference to) a private data member, such that the caller cannot modify that private
You could return a copy of the member, thus changes will not be reflected in the object the private reference points to. With primitives, of course, this problem doesn't exist.
Be mindful of memory usage, however! This might not be the right solution for all situations. In that case, an immutable object as suggested in another answer might be the way to go.