考虑以下代码:
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
但使用cmd失败
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
。
答案 0 :(得分:1)
仅在删除具有动态存储持续时间的对象期间调用operator delete
函数。您的程序没有调用它。
但是,该标准要求即使存在虚拟析构函数,该函数也必须可用,即使该对象从未真正被动态使用过。
在C ++ 17标准中,这是[class.dtor] / 13:
在定义虚拟析构函数时(包括隐式定义),将确定非数组释放函数,就好像表达式
delete this
出现在析构函数类的非虚拟析构函数中一样。如果查找失败或释放函数的定义已删除,则程序格式错误。 [注意:这确保了与 delete-expression 对应的对象动态类型的释放函数。 —尾注]
为什么该标准要求这样做?我不知道,但是您将不得不找到其他方法来解决您的问题。也许该线程会有用:Any way to prevent dynamic allocation of a class?