NOTICE: This version of the NSF Unidata web site (archive.unidata.ucar.edu) is no longer being updated.
Current content can be found at unidata.ucar.edu.
To learn about what's going on, see About the Archive Site.
Tom Glaess <tgl@xxxxxxxxxxxxxxxxx> writes: > In netcdf 2.3.2 patch 4 (C++ interface), the destructor for NcFile has been > made protected: (code from netcdf.hh) > > (parts of NcFile class deleted for brevity) > > protected: > > // Protected destructor used to make this an abstract base class. > virtual ~NcFile( void ); ... > This makes deleting an NcFile object impossible from any outside application. > I have never seen a protected destructor before. Why was this done? It is > quite possible that I'm missing something, so if I am, please tell me. > > Also, the comment just above the destructor definition does not seem to make > sense. Unless I'm wrong, if you want to make an abstract base class, wouldn't > it need to be virtual ~NcFile( void )=0 ? I incorrectly assumed that users would only use the concrete derived classes NcNewFile and NcOldFile, which both have public destructors. This change was included in patch 4 because of a note (excerpts of which are appended) about a problem on HP-UX platforms with the previous way NcFile was specified as an abstract base class. I incorporated the suggested change, because our C++ compilers didn't complain, and our C++ interface tests still worked. Now it appears that we need to look more carefully at the original HP-UX problem. > If I'm wrong about all of this, please tell me how I can delete a > NcOld/NewFile. I'm at a loss. You can explicitly invoke the destructor for an NcOldFile or NcNewFile, since their destructors are public. If you only have an NcFile, you can't delete it, so a work-around would be to make the virtual destructor public again. Thanks for pointing out this problem. I think that deriving NcOldFile and NcNewFile from the abstract base class NcFile may be an over-zealous use of inheritance. This could be fixed up in a backward-compatible way (as suggested by Dan Schmitt, thanks Dan!) with a few macros in netcdf.hh: #define NcOldFile NcFile #define NcNewFile NcFile #define Clobber New #define NoClobber Write and a new NcFile-specific enum: enum FileMode { ReadOnly = NC_NOWRITE, Write = NC_NOCLOBBER, New = NC_CLOBBER }; and then just doing everything with NcFiles. If anyone sees any problems with this approach, please let me know. ______________________________________________________________________________ Russ Rew UCAR Unidata Program russ@xxxxxxxxxxxxxxxx http://www.unidata.ucar.edu Subject: C++ interface To: russ@xxxxxxxxxxxxxxxx Date: Tue, 31 Jan 1995 14:33:41 +0000 (GMT) ... I see that someone is working on the C++ interface. I will therefore use this opportunity to make the following minor suggestion for improvement. The netcdf.hh file defines a pure virtual destructor in order to define an abstract base class: // Pure destructor used to make this an abstract base class. virtual ~NcFile( void ) = 0; My compiler (HP-CC) does not like this and complains about an unsatisfied symbol because it apparently believes that pure virtual destructors are not allowed (I think my compiler is correct in this matter, a pure destructor is not allowed to exist while the destructor is always supposed to be executed when the base of the object is destroyed even in the case where nothing except the basic destruction of builtin variables is done). Anyway, in order to illustrate the problem the following simple program ********************************* class XX { public: virtual ~XX()=0; }; class YY { public: virtual ~YY() {;} }; main() { YY y; return 0; } ********************************* leads to the following error message on my platform (HP9000/720): CC: "simple.cc", line 1: warning: please provide an out-of-line definition: XX::~XX() {}; which is needed by derived classes (245) /bin/ld: Unsatisfied symbols: XX::~XX(void) (code) *** Error code 1 I use the following workaround in netcdf.hh *********************************** protected: // a protected destructor makes a class an abstract base class virtual ~NcFile( void ); public: // Pure destructor used to make this an abstract base class. ... // virtual ~NcFile( void ) = 0; ... ************************ I suggest that you specify the virtual base class by making the destructor or equivalently a dummy constructor protected. This has the same effect, but is not illegal. Protected constructors and/or destructors prevent the definition of objects except through their own children which is what you want to achieve. ...
netcdfgroup
archives: