我要做的是重载delete操作符,使类在删除指针后自动将指针设置为null,这样我就可以在成员函数中安全地删除它,如下所示:
# 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,它调用了两次析构函数,是否像我想做的那样在类中将指针设置为空?(产出)
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发布于 2021-01-22 02:17:49
如果滥用ptr,你可能会:
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);
}演示
发布于 2021-01-22 00:52:01
不是的。无法重载operator delete,使其将指针设置为null。
这是因为标准要求operator delete的第一个参数(即要删除的指针)具有void*类型,因此operator delete只接收指针的副本,不能修改原始参数。它不能有void*&类型。(在C++20中,支持“销毁删除”,在这种情况下,参数应该具有C*类型,但仍然不允许引用。)
该实现允许在删除表达式之后将指针归零,这是一种帮助程序员捕获使用后使用的bug的技术,但是没有办法自己去做。
发布于 2021-01-22 00:47:51
是否有适当的方法将指针设置为空,就像我想做的那样?
不,这既不可能,也没有帮助。
这
void operator delete(void * ptr)
{
::delete (Buddy*)ptr;
ptr = nullptr;
}由于函数通过值接收ptr,因此ptr = nullptr;无法工作,因此ptr = nullptr;只修改本地副本。
即使有可能,如果Buddy不是由new创建的,也于事无补。在任何情况下都是个糟糕的设计。
https://stackoverflow.com/questions/65837710
复制相似问题