私はオーバーロード演算子deleteを試しています。これにより、スマートポインターを操作したくないユーザーにプレーンポインターを返すことができ、オブジェクトが削除されるタイミングを制御できます。
私は、いくつかの魂で構築され、何もしないオーバーロードされた演算子deleteと、魂の数を減らす(そして自慢する)デストラクタを持つクラスCatを定義します。魂が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を使用してコンパイルしていますが、コンパイラのバグである可能性がありますか?
ところで、repotr()の代わりにcout << *pのようにoperator<<()を使用すると、それも奇妙でした。演算子<<()内からコンストラクターを呼び出す無限ループに入りました。何が起きてる?:)
ありがとう!