首页 > 解决方案 > 是否可以重载删除运算符以将指针设置为空?

问题描述

我想要做的是重载我的类的删除运算符,以便在删除它后自动将指针设置为空,这样我就可以在成员函数中安全地删除它,如下所示:

# include <iostream>

class Buddy
{
    public:

    Buddy(void) : _hp(100) { }
    ~Buddy(void) { std::cout << "Buddy is dead!" << std::endl; }

    void operator delete(void * ptr)
    {
        ::delete (Buddy*)ptr;
        ptr = nullptr;
    }

    void getDamage(int amount)
    {
        _hp -= amount;
        if (_hp <= 0)
            delete this;
    }


    private:

    int _hp;
};

void hitBuddy(Buddy *buddy)
{
    if (!buddy)
        std::cout << "Buddy is already dead!" << std::endl;
    else
    {
        std::cout << "Hitting buddy!" << std::endl;
        buddy->getDamage(70);
    }
}

int main(void)
{
    Buddy *dude = new Buddy;

    hitBuddy(dude);
    hitBuddy(dude);
    hitBuddy(dude);
    return (0);
}

但是它没有将指针设置为 null 并且它调用了两次析构函数,有没有像我想要的那样在类中将指针设置为 null 的正确方法?(输出)

Hitting buddy!
Hitting buddy!
Buddy is dead!
Buddy is dead!
Hitting buddy!
Buddy is dead!
Buddy is dead!
a.out(79480,0x10d3cbdc0) malloc: *** error for object 0x7fe345c05790: pointer being freed was not allocated
a.out(79480,0x10d3cbdc0) malloc: *** set a breakpoint in malloc_error_break to debug
[1]    79480 abort      ./a.out

标签: c++

解决方案


不,不可能重载operator delete,以便将指针设置为空。

这是因为标准要求第一个参数 to operator delete(即要删除的指针)具有类型void*,因此operator delete只接收指针的副本并且不能修改原始参数。它不能有 type void*&。(在 C++20 中,支持“破坏删除”,在这种情况下,参数应具有类型C*,但仍不允许引用。)

实现允许在删除表达式之后将指针归零,作为一种帮助程序员捕获释放后使用错误的技术,但您自己无法做到这一点。


推荐阅读