c++ - 为什么运算符删除重载不会在调用删除时调用无限递归调用
问题描述
由于无限递归调用,调用 operator new 的局部重载会导致堆栈溢出,但是当 operator delete 的局部重载发生同样的情况时,为什么会调用全局 operator delete(从而避免堆栈崩溃)。简单的代码是这样的——
class A {
public:
void * operator new(size_t n) {
//return new A();calls local overloaded version and stack overflows
return ::new A();
}
void operator delete(void* p)
{
delete(p);//why its calling global version?
//::delete(p);//calls global version
}
};
int main()
{
A *a = new A();
delete(a);
}
我的问题是为什么从重载运算符 delete 中删除不调用自身,而是全局运算符 delete?
解决方案
我正在尝试将我的评论总结为答案。
delete
是关键字,而不是函数或运算符。所以它的行为不像函数。
当您编写 时delete p
,编译器不会像函数一样执行重载查找。当编译器遇到表达式时,它会在指针类型的delete p
可用重载之间进行查找。If是指向类的指针,并且存在特定于类的重载 then被调用。否则,编译器会在 scoped 之间执行查找。operator delete
p
p
p->operator delete(some_ptr)
void operator delete(void*)
回到你的例子。
A *a = new A();
delete(a); // a is pointer to class, calls a->operator delete(a);
void A::operator delete(void* p) {
delete(p); // p is pointer to void, calls ::operator delete(p);
}
如果你调用operator delete(a);
,它就像一个函数调用,并且A::operator delete(void*);
不会被调用。
如果你operator delete(p);
从 内部调用A::operator delete(void* p);
,你会得到无限递归。
如果您delete static_cast<A*>(p);
从 内部调用A::operator delete(void* p);
,您将再次获得无限递归。
推荐阅读
- heroku - 运行 Cloudinary 插件与现有的带有载波集成的 RoR 相比有什么好处吗
- python-3.x - 逐个循环播放jpgs以下载到计算机
- apache-spark - 如何提交不同语言的 Spark 应用程序?
- python - 函数内部的变量是通过对象全局还是局部访问?[Python]
- visual-studio-code - 一个标准输出如何通过管道传输到父进程的标准输出?
- c# - 如何以编程方式绑定生成的组合框
- ansible - Ansible 剧本替换模块未按预期运行
- c# - 使用资源字符串进行枚举序列化
- javascript - 在 REACT.js 中,如何将状态从子组件传递到父组件作为道具
- flutter - FadeTransition 和 AnimatedOpacity 彼此不同步