Re: What happened to the NcFile destructor?

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.

   ...


  • 1995 messages navigation, sorted by:
    1. Thread
    2. Subject
    3. Author
    4. Date
    5. ↑ Table Of Contents
  • Search the netcdfgroup archives: