The most common reason is, there simply is no Team object, a int or enum will suffice.
But your assertions are slightly flawed. So let my iterate on them and finally tell you why an int is also a good idea even with a Team object.
First, yes a short may be smaller than a pointer. True on a PC, but it is nowhere guaranteed. (Yes, this is sort of academic.) I doubt that saving or sending 16 bits or 64 bits makes such a difference really and you do not want to send the pointer's address anyway. If you have an IP network to sync over, the network's structure will certainly determine how fast you can sync the player state.
As noted above, you never want to send the address of a pointer over a network or save into a file. You need a way to represent this information in a stable way, thus you give each team and id (int) and store/send this. The receiving/reading end then looks up the team from that id.
At this point you can put a pointer to the Team into the Player object. It has no or little effect to storing or syncing objects.
There may be a reason why you still don't want to refer to other game objects by pointer, but this depends on your engine design. For example you may have some delayed message mechanic. So you send a message to the object (maybe even to itself) to be delivered later, but in the meantime the object is deleted. By using a unique int it is possible to safely handle the message, the lookup fails and the message can be silently ignored. If it was a hardcoded pointer it would have crashed. You see this type of safety or weak references can often be found in code. (Google "Handle" for more info.)
And on a closing note, "It's more OOP". We are software engineers and not software zealots, thus we don't adhere to dogma. Any design discussion must based on real principles that have a well defined gain. Any person that says this is the right way to do it should get their brains unwashed. It don't want to say that OOP is bad, no it is great, but "this is the right way to do OOP" is a non starter.