2011-09-08 92 views
0

我有一个单例(我知道这是一个不好的模式)。为了控制清洁过程,我使用了一个共享指针。相关的代码是:当应用程序正在完成时未处理的异常

#ifndef _GLOBAL_LOG_H_ 
#define _GLOBAL_LOG_H_ 

    namespace glog{ 

     class CGlobalLog; 
     typedef boost::shared_ptr<CGlobalLog> globalLogPtr; 

     class CGlobalLog 
     { 
     private: 

      static globalLogPtr m_instance; 
      LogLevel minimiumLogLevel; 
      CGlobalLog(void); 

      static void deleter(CGlobalLog *ptr){ 
       try{ 
        delete ptr; 
       } 
       catch(std:: e) 
       { 
        std::cout << e.what() << "\n"; 
       } 
      } 
      static void create() { m_instance.reset(new CGlobalLog, &CGlobalLog::deleter); } 
      void addMessage_(const std::string& appender, LogLevel level /*= LOGLEVEL_INFO*/,const char* msg, va_list args); 
      ~CGlobalLog(void); 
     public:   
      static globalLogPtr& getInstance(); 
      void addMessage(const std::string& message, std::string appender, LogLevel level = LOGLEVEL_INFO); 

     }; 
     globalLogPtr CGlobalLog::m_instance; 
    }; 

#endif // _GLOBAL_LOG_H_ 

程序工作正常,但是当节目结束,未处理的异常在这一点上抛出:

static void deleter(CGlobalLog *ptr){ 
    try{ 
     delete ptr; //<-- Unhandled exception 
    } 
    catch(std:: e) 
    { 
     std::cout << e.what() << "\n"; 
    } 
} 

渔获不捕获异常,所以我不要”不知道如何处理我的错误。错误被抛出的确切代码是一个boost库文件checked_delete.hpp,在这里:

// verify that types are complete for increased safety 

template<class T> inline void checked_delete(T * x) 
{ 
    // intentionally complex - simplification causes regressions 
    typedef char type_must_be_complete[ sizeof(T)? 1: -1 ]; 
    (void) sizeof(type_must_be_complete); 
    delete x; 
} 

我该如何找到这个错误?一些想法?

谢谢!

+2

为什么你有一个自定义删除? –

+2

这条线是什么意思? catch(std :: e)' –

+1

以及为什么你从getInstance返回_reference_到std :: shared_ptr? –

回答

1

我通常不希望在单例中看到共享指针。只要返回一个对你的单例的引用,并且从不保留对它的引用就是一个好习惯。

struct Foo { 
    static Foo &instance() { 
    static Foo foo; 
    return foo; 
    } 
}; 

struct Bar { 
    void someMethod() { 
    Foo &foo = Foo::instance(); // just grab a reference every time you need it 
    // ... 
    } 
}; 

如果您希望保留共享指针并需要以手动方式清理资源,请创建拆卸方法。 boost::shared_ptr将最终清理内存。

就我个人而言,我认为在外部使用共享指针是次等的。我写了一些代码来展示拆除,并且在不知道你为什么需要它的情况下似乎并不普遍适用。

如果你想显式删除,然后写一个。

struct Foo { 
    static Foo *foo = 0; 
    static Foo &instance() { 
    if (!foo) 
     throw std::logic_error("Already deleted"); 
    return *foo; 
    } 
    static void Init() { 
    if (foo) 
     throw std::logic_error("Already created"); 
    foo = new Foo; 
    } 
    static void Destroy() { 
    if (!foo) 
     throw std::logic_error("Already deleted"); 
    delete foo; 
    foo = 0; 
    } 
}; 

在记录的情况下,逻辑错误应该是多余的。如果在您要求时记录无效,那么您的应用程序不太可能处于有效状态。

+1

**如果您必须使用'reset()'方法删除** boost :: shared_ptr':http://stackoverflow.com/questions/621233/how-to-intentionally-delete-a-boostshared-ptr – karlphillip

+0

如前所述,shared_pointer是强制破坏调用的一种技巧。 – Killrazor

+0

@Killrazor你不能为此使用'boost :: shared_ptr'。共享指针的每个副本都拥有内存,这就是整个点。如果你想强制销毁,那么你必须自己管理记忆。 –

相关问题