Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is this error message about implicitly deleted virtual destructors?

I've just updated GCC from (I think) 4.5.6 to 4.6.1, under Windows, MinGW. Suddenly my NonInstantiable base class (from which you inherit with public virtual to prevent instantiation) refuses to work with the following and similar error messages:

#ifndef Frigo_Lang_NonInstantiable
#define Frigo_Lang_NonInstantiable

namespace Frigo
{
namespace Lang
{

/**
*   Inherit from this class if you want to make a non-instantiable class. Most
*   useful for static classes. It seems every inheritance combination
*   (public/protected/private, non-virtual/virtual) shuts off instantiation in
*   all subclasses as well.
**/

class NonInstantiable
{
private:
/*  Private Classes  */

    /**
    *   A dummy class to prevent GCC warnings about virtual
    *   constructors/destructors and no friends
    **/
    class NonInstantiableDummy { };

/*  Private Constructors  */

    /**
    *   Private constructor to prevent instantiation
    **/
    NonInstantiable() { }

    /**
    *   Private destructor to prevent instantiation on the stack. Virtual to
    *   prevent GCC warnings
    **/
    virtual ~NonInstantiable() { }

/*  Friends  */
    friend class NonInstantiableDummy;
};

}
}

#endif

Errors:

/code/Frigo/Util/Arrays:40:7: error: deleted function 'virtual Frigo::Util::Arrays::~Arrays()'
/code/Frigo/Lang/Object:37:11: error: overriding non-deleted function 'virtual Frigo::Lang::Object::~Object()'
/code/Frigo/Util/Arrays:40:7: error: 'virtual Frigo::Util::Arrays::~Arrays()' is implicitly deleted because the default definition would be ill-formed:
/code/Frigo/Lang/NonInstantiable:39:11: error: 'virtual Frigo::Lang::NonInstantiable::~NonInstantiable()' is private
/code/Frigo/Util/Arrays:40:7: error: within this context
/code/Frigo/Lang/NonInstantiable:39:11: error: 'virtual Frigo::Lang::NonInstantiable::~NonInstantiable()' is private
/code/Frigo/Util/Arrays:40:7: error: within this context
/code/Frigo/Util/Arrays:40:7: error: deleted function 'virtual Frigo::Util::Arrays::~Arrays()'
/code/Frigo/Lang/NonInstantiable:39:11: error: overriding non-deleted function 'virtual Frigo::Lang::NonInstantiable::~NonInstantiable()'

I suspect it is because I do not create any destructors, virtual or otherwise, in the child classes, and this somehow conflicts with the private virtual destructor of NonInstantiable, but I need confirmation. And a solution how to fix my NonInstantiable class to suppress these errors, but still work.

like image 853
Frigo Avatar asked Sep 28 '11 17:09

Frigo


People also ask

What happens if destructor is not virtual?

Deleting a derived class object using a pointer of base class type that has a non-virtual destructor results in undefined behavior.

What is the purpose of virtual destructor in C++?

A virtual destructor is used to free up the memory space allocated by the derived class object or instance while deleting instances of the derived class using a base class pointer object.

Is destructor virtual by default C++?

The destructor is not user-provided (meaning, it is either implicitly declared, or explicitly defined as defaulted on its first declaration) The destructor is not virtual (that is, the base class destructor is not virtual) All direct base classes have trivial destructors.

Should all destructors be virtual?

You might need an explicitly defined destructor for other reasons, but there's no need to redeclare a destructor simply to make sure it is virtual. No matter whether you declare it with the virtual keyword, declare it without the virtual keyword, or don't declare it at all, it's still virtual.


1 Answers

Parent destructors always need to be callable from a child class (because this happens automatically) and so parent class destructors can't be private.

Just make your NonInstantiable's destructor protected.

Also note that a child class could circumvent the parent as written by explicitly (accidentally?) calling into its public compiler-generated copy constructor.

EDIT: I should add as an aside that you might want to consider your need for a non-instantiable class here. I personally believe that a combination of free functions and anonymous-namespace variables would be a cleaner way of doing this.

like image 156
Mark B Avatar answered Sep 30 '22 16:09

Mark B