What is this error message about implicitly deleted virtual destructors?
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.
Frigo
Updated on June 07, 2022Comments
-
Frigo about 2 years
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.
-
Captain Giraffe over 12 yearsA private destructor, thats seems just mean to me. Care to explain you comments in your code from the link? Edit: Mark B's answer explains it.
-
Frigo over 12 yearsWell, the class tries to prevent instantiation (in subclasses as well) by declaring a private constructor and destructor. The destructor needs to be virtual otherwise GCC whines at inheritance. The friend inner class need to be there as well otherwise GCC whines.
-
Captain Giraffe over 12 yearsWhat is your use-case? Why do you need this? I'm very curious.
-
Frigo over 12 yearsJust to prevent accidental instantiation of static classes (aka "storage classes" aka "utility classes"). There is some
static
keyword to mark such classes, but IIRC it allows only static methods, it throws a fit when it sees a static variable. -
Mike Seymour over 12 years@Frigo: in C++, you'd usually use a namespace for that, and only define a class when you actually want an instantiable type. "Static classes" only make sense in languages that force you to put everything in a class.
-
Frigo over 12 yearsSometimes I need static variables and methods that are private (for example, the internals of Arrays::quicksort). Namespace scope variables and methods are not perfect, they are accessible by everyone and this can cause complications. I prefer them being in classes. Anonymous namespaces help the situation somewhat, but their advantages are negligible.
-
-
Frigo over 12 yearsGood call at making the destructor private. Is this due to some recent language change part of C++11 or just a GCC bugfix to better conform? Also, created a private copy constructor as well just to be sure ;)