c++ - 为什么运算符删除重载不会在调用删除时调用无限递归调用

标签 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();
    }

    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 p时,编译器不会对函数之类的重载执行查找。当编译器满足表达式delete p时,它将在可用重载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);,则会再次获得无限递归。

关于c++ - 为什么运算符删除重载不会在调用删除时调用无限递归调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61034068/

相关文章:

c++ - 带有命令行参数的 C++ Makefile 和 Bash 脚本

c++ - 为什么我的 WndProc 不能在类里面?

c++ - 删除结构的指针是否也会删除结构内的指针?

c++ - *** 检测到 glibc *** ./burcu.exe : free(): invalid next size (fast): 0x000000001dad6310 ***

c++ - 删除在另一个函数中分配的内存?

c++ - 在循环中创建新的指针对象

c++ - 如何将元素添加到链表的末尾

c++ - 将数据放入 Opencv 中的 Mat 对象中

c++ - execve() 是做什么的?

c++ - std::list remove 在指针上调用 delete?