我正在尝试重载运算符 delete,以便我可以将一个普通指针返回给那些不希望使用智能指针的人,但能够控制何时删除对象。
我定义了一个 Cat 类,它由多个灵魂构成,有一个不执行任何操作的重载运算符 delete,以及减少灵魂数量的析构函数(并且还做一些吹牛)。当 souls 达到 0 时,析构函数调用全局 ::delete,猫就死了。
这听起来很简单,但并不像预期的那样工作。这是代码:
class Cat {
public:
Cat(string n): name(n), souls(9)
{ cout << "Myaou... " << name << " is born\n"; }
~Cat();
void operator delete(void *p) { cout << "!!! operator delete called\n"; }
void report()
{ cout << name << "'s here, " << souls << " souls to spend\n"; }
friend ostream& operator<< (const ostream& o, const Cat& cat);
private:
void kill();
const string name;
int souls;
};
Cat::~Cat()
{
cout << "!!! dtor called\n";
kill();
}
void Cat::kill()
{
if (--souls)
cout << name << " is still alive! I have " << souls << " souls left.\n";
else {
cout << name << " is dying... good bye world!\n";
::delete((void*)this);
}
}
ostream& operator<< (const ostream& o, const Cat& cat)
{
return o << cat.name << "'s here, " << cat.souls << " souls to spend\n";
}
这是主要的:
int main()
{
Cat *p = new Cat("Mitzi");
for (;;)
{
char c[100];
// cout << *p;
p->report();
cout << "come on, hit me!";
cin >> c;
delete p;
}
}
我希望循环会运行 9 次,然后会发生一些不愉快的事情(崩溃)。但是,这是输出:
Myaou... Mitzi is born
Mitzi's here, 9 souls to spend
come on, hit me!c
!!! dtor called
Mitzi is still alive! I have 8 souls left.
!!! operator delete called
's here, 8 souls to spend
come on, hit me!c
!!! dtor called
is still alive! I have 7 souls left.
*** glibc detected *** /home/davidk/workspace/string_test/Debug/string_test: double free or corruption (fasttop): 0x080cd008 ***
似乎在第一次删除后,名称成员被破坏,下一次删除导致崩溃。有什么解释吗?我在 Linux 上使用 gcc 编译,可能是编译器错误吗?
顺便说一句,当我在 cout << *p 中使用 operator<<() 而不是 repotr() 时,这也很奇怪:它进入了从 operator<<() 中调用构造函数的无限循环。这里发生了什么?:)
谢谢!