How to catch exception thrown while initializing a static member

后端 未结 5 615
轻奢々
轻奢々 2020-12-18 01:06

I have a class with a static member:

class MyClass
{
public:
    static const SomeOtherClass myVariable;
};

Which I initialize in the CPP f

5条回答
  •  独厮守ぢ
    2020-12-18 01:44

    You could make a wrapper class that delays construction of the object. Then when its first used, it will throw where ever its first used, if the constructor throws.

    This has the benefit of not having alot of code run before main() is called, and if you don't ever actually use the global object it won't ever be initialized.

    The code:

    #include 
    #include 
    #include 
    #include 
    #include 
    
    const boost::once_flag DEFAULT_ONCE_FLAG = BOOST_ONCE_INIT;
    template 
    class DelayedConstruction {
      public:
      DelayedConstruction(boost::function const & init = &DelayedConstruction::default_initializer ) :
        m_initializer(init), m_flag(DEFAULT_ONCE_FLAG) { }
    
      T const & operator*() const { 
        boost::call_once(m_flag, boost::bind(&DelayedConstruction::initialize, this) ) ;
        if ( ! m_object )
          throw std::runtime_error("Object could not be initialized") ;
        return *m_object ;
      }
      T const * operator->() const {
        boost::call_once(m_flag, boost::bind(&DelayedConstruction::initialize, this) ) ;
        if ( ! m_object )
          throw std::runtime_error("Object could not be initialized") ;
        return m_object.get() ;
      }
      static T* default_initializer() { return new T; }
      private:
      void initialize() const {
        m_object.reset( m_initializer() ) ;
      }
      boost::function m_initializer ;
      mutable boost::scoped_ptr m_object ;
      mutable boost::once_flag m_flag ; 
    };
    
    struct Foo {
      Foo(int x = 0) : m_x(x) {
        if ( x == 1 ) throw std::runtime_error("Can't be 1") ;
      }
      int m_x ;
    } ;
    
    Foo* make_custom_foo() {
      return new Foo(1) ;
    }
    
    DelayedConstruction< const Foo > g_myFoo ;
    DelayedConstruction< const Foo > g_anotherFoo(&::make_custom_foo) ;
    
    int main() {
    
      try {
        std::cout << "My Foo: " << g_myFoo->m_x << std::endl ;
        std::cout << "Another Foo: " << g_anotherFoo->m_x << std::endl ;
      } catch ( std::runtime_error const & e ) {
        std::cout << "ERROR: " << e.what() << std::endl ;
      }
    
      return 0 ;
    }
    

    Prints out:

    My Foo: 0
    ERROR: Can't be 1
    

提交回复
热议问题