Search code examples
c++11operator-keywordvirtual-destructor

Why does a virtual destructor require operator delete?


Consider the following code:

class Base {
public:
#ifdef __VIRTUAL__
   virtual ~Base() {}
#else
   ~Base() {}
#endif
};

class Derived : public Base {
public:
    ~Derived() {}
private:
    static void operator delete(void*) = delete;
};

int main() {
    Derived d;
}

It'll compiled successfully with cmd

g++ -std=c++11 main.cpp

but failed with cmd

g++ -std=c++11 -D__VIRTUAL__ main.cpp

The output shows the operator delete is required

main.cpp: In destructor ‘virtual Derived::~Derived()’:
main.cpp:12:17: error: use of deleted function ‘static void Derived::operator delete(void*)’
     ~Derived() {}
                 ^
main.cpp:14:17: error: declared here
     static void operator delete(void*) = delete;
                 ^
main.cpp: In destructor ‘virtual Derived::~Derived()’:
main.cpp:12:17: error: use of deleted function ‘static void Derived::operator delete(void*)’
     ~Derived() {}
                 ^
main.cpp:14:17: error: declared here
     static void operator delete(void*) = delete;
                 ^

It means that if I use virtual destructor function, I cannnot delete operator delete .

Why is this happened, why virtual destructor required global operator delete even if created on stack.


Solution

  • The operator delete function is only called during deletion of an object with dynamic storage duration. It's not called by your program.

    However, the standard requires that this function be available if there is a virtual destructor, even if the object is never actually used dynamically.

    In the C++17 standard this is [class.dtor]/13:

    At the point of definition of a virtual destructor (including an implicit definition), the non-array deallocation function is determined as if for the expression delete this appearing in a non-virtual destructor of the destructor’s class. If the lookup fails or if the deallocation function has a deleted definition, the program is ill-formed. [Note: This assures that a deallocation function corresponding to the dynamic type of an object is available for the delete-expression. —end note ]

    Why does the standard require this? I have no idea but you're going to have to find some other approach to solve your problem. Maybe this thread will be useful: Any way to prevent dynamic allocation of a class?