2013-02-18 18 views
11

Bu Birisi başka bir sınıfın yıkıcı MyClass oluşturuyorsa bu algılamak istiyorum Why can't Alexandrescu use std::uncaught_exception() to implement SCOPE_FAIL in ScopeGuard11?Başka bir yıkıcıyı yürütürken bir nesnenin oluşturulup oluşturulmadığını tespit etmek için herhangi bir numara var mı?

takip tür olan (ya da bir yere çağrı yığını içinde aktif yıkıcının birlikte).

class MyClass 
{ 
public: 
    MyClass(){ 
     assert(???what to put here????); 
    } 
} 

void f(){ 
    MyClass m; //whether this asserts should be context dependant 
} 

class OtherClass{ 
    ~OtherClass(){ 
     MyClass m; //this should assert 
     f();  //this should too; 
    } 
} 

int main() 
{ 
    MyClass m; //this should not assert 
    f();   //this should also not assert 
} 

bir teşebbüs olabilir:

assert(!std::uncaught_exception()); 

ama yıkıcı özel durum nedeniyle çağrılan olup olmadığını sadece nesne kapsam dışına çıktı çünkü çağrıldığında değilse çalışacak.

+7

Bu yıkıcıları, icralarını herhangi bir şekilde işaret etmek için açıkça tasarlamadıkça, bunun mümkün olduğundan şüpheliyim. Genel olarak, işlevinizin nerede çağrıldığını söyleyemezsiniz. –

+0

Çözümün ne kadar taşınabilir olmasını istiyorsunuz? – Flexo

+0

Çözümünüzü belirli bir derleyici sürümüyle özelleştirebilir ve 'OtherClass' nesnesini bulmak için yığını MyClass'ın yapıcısını inceleyebilirsiniz. Ben şahsen, bunun ne olduğu için çok fazla iş olduğunu düşünüyorum ... ve bir hata kaynağı olacak. – Synxis

cevap

1

bunu algılayamıyorsunuz ve istemiyorsunuz. Bu senin sınıfın işi değil. Eğer birisi sizi mutsuz bir yıkıcıdan arayacaksa, istisnaları yakalayacaktır

0

Arayanların bu bilgileri sağlamasını sağlamadığınız sürece, işlevinizin nasıl çağrıldığını algılayamazsınız. Ayrıca

, bunu hiçbir yıkıcı herhangi try blok çağrılan biliniyordu hatta Visual C++ o ungood olacağını bu yüzden (taşınabilir kodu), std::uncaught_exception uygulamaya asla hatırlayın. Ancak, bir özel durum nedeniyle bir kapsamın çıkıp çıkmadığını algılamak önemsizdir.

Bu kapsamı try-blokta koymanız yeterli; İşte bunun için. Örneğin

,

class Transaction 
{ 
private: 
    bool failed_; 
    Transaction(Transaction const&); // deleted 
    Transaction& operator=(Transaction const&); // deleted 

public: 
    void fail() { failed_ = true; } 

    void commit() { ... } 

    // More functionality, then 

    ~Transaction() 
    { 
     if(failed_) { rollback(); } 
    } 

    Transaction(): failed_(false) {} 
}; 

void foo() 
{ 
    Transaction transaction; 

    try 
    { 
     // blah blah 
    } 
    catch(...) 
    { 
     transaction.fail(); 
     throw; 
    } 
} 

Yasal Uyarı: Ne kadar pratik kanıtı olamaz böylece desen kullanmadım.

İlgili konular