为什么虚拟析构函数需要运算符删除?

Why does a virtual destructor require operator delete?

考虑以下代码:

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;
}

用cmd编译成功

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

但使用命令失败

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

输出显示 operator 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;
                 ^
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;
                 ^

意思是如果我使用虚析构函数,我不能删除operator delete

为什么会这样,为什么虚拟析构函数需要全局 operator delete 即使在堆栈上创建。

operator delete函数仅在删除具有动态存储持续时间的对象时调用。它不是由您的程序调用的。

但是,标准要求如果存在虚拟析构函数,则此函数可用,即使该对象从未实际动态使用过。

在 C++17 标准中,这是 [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 ]

为什么标准有这个要求?我不知道,但你将不得不找到其他方法来解决你的问题。也许这个帖子会有用:Any way to prevent dynamic allocation of a class?