首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >是否可以重载delete操作符将指针设置为null?

是否可以重载delete操作符将指针设置为null?
EN

Stack Overflow用户
提问于 2021-01-22 00:29:13
回答 3查看 95关注 0票数 0

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

代码语言:javascript
复制
# 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,它调用了两次析构函数,是否像我想做的那样在类中将指针设置为空?(产出)

代码语言:javascript
复制
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
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2021-01-22 02:17:49

如果滥用ptr,你可能会:

代码语言:javascript
复制
class Buddy
{
    Buddy() = default;
    Buddy(const Buddy&) = delete;
    Buddy& operator=(const Buddy&) = delete;
public:

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

    void getDamage(int amount)
    {
        _hp -= amount;
        if (_hp <= 0)
            self.reset();
    }

    static std::weak_ptr<Buddy> make() { auto p = new Buddy; return p->self; }

private:
    int _hp = 100;
    std::shared_ptr<Buddy> self{this};
};

void hitBuddy(std::weak_ptr<Buddy> buddy_weak)
{
    auto buddy = buddy_weak.lock();

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

int main()
{
    std::weak_ptr<Buddy> dude = Buddy::make();

    hitBuddy(dude);
    hitBuddy(dude);
    hitBuddy(dude);
}

演示

票数 2
EN

Stack Overflow用户

发布于 2021-01-22 00:52:01

不是的。无法重载operator delete,使其将指针设置为null。

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

该实现允许在删除表达式之后将指针归零,这是一种帮助程序员捕获使用后使用的bug的技术,但是没有办法自己去做。

票数 4
EN

Stack Overflow用户

发布于 2021-01-22 00:47:51

是否有适当的方法将指针设置为空,就像我想做的那样?

不,这既不可能,也没有帮助。

代码语言:javascript
复制
void operator delete(void * ptr)
    {
        ::delete (Buddy*)ptr;
        ptr = nullptr;
    }

由于函数通过值接收ptr,因此ptr = nullptr;无法工作,因此ptr = nullptr;只修改本地副本。

即使有可能,如果Buddy不是由new创建的,也于事无补。在任何情况下都是个糟糕的设计。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65837710

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档