Throw on access to objects from closed files

Because libhdf5 reuses IDs, we need to throw when a closed object is
accessed instead of relying on libhdf5 to do so. Otherwise, a user may
think they're accessing one object when in actuality they're accessing
a different object.