gpt4 book ai didi

c++ - 使用析构函数处理失败与 catch (...) { fix();扔; }

转载 作者:搜寻专家 更新时间:2023-10-31 01:05:38 24 4
gpt4 key购买 nike

假设我正在做一些在抛出异常时需要清理的事情。

比如我正在创建一个动态数组,我需要构造对象,但是它们的构造函数可能会抛出异常:

size_t const n = 100;
T *const p = static_cast<T *>(operator new(sizeof(T) * n));
size_t i;
for (i = 0; i < n; ++i)
new (&p[i]) T(1, 2, 3); // Not exception-safe if T::T(T const &) throws!

我可以通过 catch (...) { ...; 修复它扔; :

size_t const n = 100;
T *const p = static_cast<T *>(operator new(sizeof(T) * n));
size_t i;
try
{
for (i = 0; i < n; ++i)
new (&p[i]) T(1, 2, 3);
}
catch (...)
{
while (i > 0)
p[--i].~T();
operator delete(p);
throw;
}

或通过作用域析构函数:

size_t n = 100;
struct Guard
{
T *p;
size_t i;
Guard(size_t n) : i(), p(static_cast<T *>(operator new(sizeof(T) * n))) { }
~Guard()
{
while (i > 0)
p[--i].~T();
operator delete(p);
}
} guard(n);

for (guard.i = 0; guard.i < n; ++guard.i)
new (&guard.p[guard.i]) T(1, 2, 3);

guard.i = 0; // Successful... "commit" the changes
guard.p = NULL; // or whatever is necessary to commit the changes

我应该在什么时候使用哪种技术,为什么?

(注意:此示例旨在显示两种技术之间的区别。我知道它不是完美的代码,所以请不要 关注这个特定的例子。它只是为了说明。)

最佳答案

使用析构函数的解决方案比显式的try/catch更好:

  • 它是可重用的,如果你需要在另一个函数中做类似的初始化,你可以重用相同的守卫类
  • 它更容易维护 - 假设在某些情况下您的函数需要返回失败但不抛出异常。使用守卫类,它或多或少会自动处理
  • 它更干净,因为代码更加模块化

关于c++ - 使用析构函数处理失败与 catch (...) { fix();扔; },我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22347089/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com