This archive contains answers to questions sent to Unidata support through mid-2025. Note that the archive is no longer being updated. We provide the archive for reference; many of the answers presented here remain technically correct, even if somewhat outdated. For the most up-to-date information on the use of NSF Unidata software and data services, please consult the Software Documentation first.
Hi Tom, > 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 ? Oops, I thought people were only using the derived concrete classes NcNewFile and NcOldFile, which both have public destructors. I made this change because of the appended note I got in January about a problem with the way I had been making NcFile an abstract base class. I accepted his suggested solution uncritically, because the compilers didn't squawk when I tried it, and all my tests still worked. Now it appears that I'll have to look more carefully at the HP-UX problem that caused this ... > 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 have an NcFile, it looks like this is a problem. Thanks for pointing this out. Incidentally, I'm thinking that the idea of having NcOldFile and NcNewFile derived from the abstract base class NcFile was actually a case of poorly-designed inheritance that needs to be corrected in release 2.4. I think this can be fixed up in a backward compatible way (as suggested by Dan Schmitt) with a few macros in netcdf.hh, something like: #define NcOldFile NcFile #define NcNewFile NcFile #define Clobber New #define NoClobber Write with new class-specific enum: enum FileMode { ReadOnly = NC_NOWRITE, Write = NC_NOCLOBBER, New = NC_CLOBBER }; and then just doing everything with NcFiles. Do you have any opinions about or see any problems with this approach? --Russ Subject: C++ interface To: address@hidden Date: Tue, 31 Jan 1995 14:33:41 +0000 (GMT) From: "Tomas Johannesson" <address@hidden> X-Mailer: ELM [version 2.4 PL23] Mime-Version: 1.0 Content-Type: text/plain; charset=iso-8859-1 Content-Transfer-Encoding: 8bit Content-Length: 4179 Dear Russ, 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., virkar ekki // 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. best wishes, tomas