2017-08-20 6 views
0

私はEffective C++ 3rd Edition、item52 "プレースメントを新規作成すると、プレースメントの削除を書く"と読んでいます。建設後に削除を呼び出すときに例外をスローする

オペレータが例外をスローした後に自動的に呼び出されるようにするにはどうすればいいですか?

#include <iostream> 
using namespace std; 

class A { 
    int i; 
public: 
    static void* operator new(std::size_t size) throw(std::bad_alloc) { 
     return malloc(size); 
    } 
    static void operator delete(void* p) throw() { 
     cout << "delete" << endl; 
     free(p); 
    } 
    A() { 
     throw exception(); 
    } 
}; 

int main() { 
    A* a = new A; 
} 

上記のコードのみ出力:

terminate called after throwing an instance of 'std::exception' 
    what(): std::exception 
[1] 28476 abort  ./test_clion 
+0

あなたがのallocメモリに失敗した場合、あなたはそれが削除 –

+0

解放カントが自動的に呼び出されます。ところで、この例は実際には配置newではなく、配置削除は直接呼び出すことはできません。しかし、それが新しい配置で、コンストラクタが例外を投げた場合、それはコンパイラが呼び出すプレースメントの削除であり、したがってあなたの本のアドバイスです。 – Mic

答えて

1

参考:operator delete, operator delete[]

私はtry {}newを記述する必要があります。今は例外についてあまり知りません。

#include <iostream> 
using namespace std; 

class A { 
    int i; 
public: 
    static void* operator new(std::size_t size) throw(std::bad_alloc) { 
     return malloc(size); 
    } 
    static void operator delete(void* p) throw() { 
     cout << "delete" << endl; 
     free(p); 
    } 
    A() { 
     throw exception(); 
    } 
}; 

int main() { 
    try { 
     A* a = new A; 
    } catch (const exception&) { 

    } 
} 

そして出力:コンストラクタがスローした場合

delete 
+0

つまり、キャッチされない例外は、トップレベルで捕捉された例外とは異なります。 – Yakk

+0

@Yakk C++はとても複雑です。実際には、 'new'が' try {} 'にあるときだけ、なぜdeleteが呼ばれるのか分かりません。 – chaosink

+0

捕捉されない例外がプログラムを終了し、スタックの巻き戻しが発生しません。キャッチされた例外は、メモリがクリーンアップされるスタックアンワインディングを引き起こします。 – Yakk

関連する問題