在阅读这个问题之前,我从未认真对待异常处理。现在我看到了必要性,但仍然觉得“编写异常安全代码非常困难”。
请参阅该问题接受的答案中的此示例:
void doSomething(T & t)
{
if(std::numeric_limits<int>::max() > t.integer) // 1. nothrow/nofail
t.integer += 1 ; // 1'. nothrow/nofail
X * x = new X() ; // 2. basic : can throw with new and X constructor
t.list.push_back(x) ; // 3. strong : can throw
x->doSomethingThatCanThrow() ; // 4. basic : can throw
}
正如答案所说,我可以通过使用轻松提供基本保证std::unique_ptr
。但是,当我捕获 a 时std::bad_alloc
,我不知道它是否发生在push_back
orx->doSomethingThatCanThrow()
中,所以我不知道 t.list 是否仍然“好”或者它的最后一个元素没有完全准备好。然后唯一的选择是丢弃 t,显示一个可怕的消息并中止,如果 t 对整个程序是必不可少的。
具有强保证的代码没有问题,但是“它可能会变得昂贵”(这个例子涉及到大列表的副本),并且不那么可读。
一个可能的解决方案可能是new
等待内存可用,从而消除最烦人的异常std::bad_alloc
。然后 2. 和 3. 不会抛出(前提X
是构造和复制总是成功)。我可以将 4. 包装在一个 try 块中并在此处处理异常(以及 pop_back 列表)。然后该函数将提供 nothrow 保证,并且列表将始终包含好东西。
用户不会关心 100% CPU 和 100% RAM 之间的区别。当他们看到一个程序挂起时,他们会关闭其他程序,以便new
找到足够的内存并继续。
我的问题:这可以实施吗?有没有等到内存可用的新方法?我可以在全球范围内应用它(例如 by #define new ...
),以便 C++ 标准化之前的库可以在临时 100% RAM 中存活吗?