Apparently there is just a single pointer used to maintain position for both read and write operations in the file stream. I'm not sure of the best documentation on this.
Well, that's workable for a small number of member variables, but it rapidly grows cumbersome. You may like to consider overloading the << and >> operators for output and input streams.
Well --- that's a pretty horrible design. Sorry to say that, I usually don't express myself so strongly.
If you must have a function which uses a while loop to read all the items from the file, make it a separate function. Don't try and stuff it inside some other function where it doesn't belong. Try to keep each function doing just one specific thing, and have it do it cleanly and well. That way, the functions are reusable. A very specialised function which does unexpected things gives, as you've discovered, unexpected results.
Since your friend ifstream& operator>> function loops through the entire file (or until there is an error) after the line i >> my; the variable my will contain the result of the very last successful read operation.
Ok, I'm sure you've got this understood by now. I just wanted to add that the way to look at it is as though the entire struct is an object, just like one of the built-in types int or double or a library type such as std::string.
Hence when we do int n; cin >> n; or string name; cin >> name; we know what to expect of the >> operator - it reads a single object of the given type from the stream. Similarly with the output <<. When adding this functionality for our own types (a struct or class), it is a good idea to keep to that pattern.