如何在初始化静态成员时捕获抛出的异常

rme*_*dor 7 c++ static exception-handling

我有一个静态成员的类:

class MyClass
{
public:
    static const SomeOtherClass myVariable;
};
Run Code Online (Sandbox Code Playgroud)

我在CPP文件中初始化如下:

const SomeOtherClass MyClass::myVariable(SomeFunction());
Run Code Online (Sandbox Code Playgroud)

问题是,SomeFunction()从注册表中读取值.如果该注册表项不存在,则会引发异常.这导致我的程序爆炸而没有给用户任何有用的输出...有什么方法我可以捕获异常,所以我可以记录它?

Mat*_* M. 7

我不太喜欢static数据成员,初始化的问题是最重要的.

每当我必须做大量处理时,我作弊并使用本地static代替:

class MyClass
{
public:
    static const SomeOtherClass& myVariable();
};

const SomeOtherClass& MyClass::myVariable()
{
  static const SomeOtherClass MyVariable(someOtherFunction());
  return MyVariable;
}
Run Code Online (Sandbox Code Playgroud)

这样,异常将仅在第一次使用时抛出,但对象将是const.

这是延迟执行的非常强大的习惯用语.它有一点开销(基本上编译器每次进入方法时都会检查一个标志),但最好先担心正确性;)

如果从多个线程调用它:

  • 如果您的编译器处理它,很好
  • 如果您的编译器没有,您可以使用本地线程存储(无论如何它是const)
  • 你可以boost::onceBoost.Threads图书馆里使用
  • 既然如此const,你可能不在乎它是否多次初始化,除非someOtherFunction不支持并行执行(小心资源)

准则:仅对简单对象(不能抛出)使用staticglobal变量实例化,否则使用local static变量来延迟执行,直到可以捕获结果异常.


Dan*_*son 5

也许最好的办法是将注册表项添加到列表而不是查找它,然后只要输入main(),就可以查看列表中的所有键.我不想说教,但是这样的情况正是为什么在输入main()之前进行重要处理通常是个坏主意.


Jer*_*fin 5

当然 - 包装SomeFunction()在以下功能中:

int static_error;

void SomeFunctionWrapper() { 
    try { 
        SomeFunction();
    }
    catch(...) { // something more specific if possible
        static_error = 1;
    }
}
Run Code Online (Sandbox Code Playgroud)

然后在进入main时,您将需要检查static_error != 0并在需要时打印相应的错误消息(遗憾的是,您无法知道std::cerr您的异常处理程序中是否存在,所以如果您想从那里打印,那么您将拥有做一些像C FILE*的输出).