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 object X when in actuality object X is closed
and object Y has been opened in the same ID.