C++ 为什么运算符删除重载不';t调用delete时调用无限递归调用
调用运算符new的本地重载会由于无限递归调用而导致堆栈溢出,但当运算符delete的本地重载发生相同情况时,为什么会调用全局运算符delete(从而避免堆栈崩溃)。 简单的代码是这样的-C++ 为什么运算符删除重载不';t调用delete时调用无限递归调用,c++,delete-operator,C++,Delete Operator,调用运算符new的本地重载会由于无限递归调用而导致堆栈溢出,但当运算符delete的本地重载发生相同情况时,为什么会调用全局运算符delete(从而避免堆栈崩溃)。 简单的代码是这样的- class A { public: void * operator new(size_t n) { //return new A();calls local overloaded version and stack overflows return ::new A();
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
时,它会在可用重载operator delete
之间对指针类型p
执行查找。如果p
是指向类的指针,并且存在特定于类的重载,则调用p->operator delete(some_ptr)
。否则,编译器将在作用域void运算符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);
}
如果您调用操作员删除(a)
,它就像一个函数调用,a::operator delete(void*)代码>未被调用
如果您调用操作符delete(p)代码>从A::operator delete(void*p)的内部代码>,得到无限递归
如果调用delete static\u cast(p)代码>从A::operator delete(void*p)的内部代码>,您再次得到无限递归。那么,您的意思是new和delete w.r.t之间的差异。无限递归只取决于参数类型(因为运算符delete需要处理void*或A*)?